文档章节

Spring Security+Struts2实现登录,注册,以及注册自动登录模块

xpbug
 xpbug
发布于 2014/11/14 18:07
字数 1426
阅读 1077
收藏 3
点赞 0
评论 0

源码

下载

半成品源码下载地址: http://pan.baidu.com/s/1bn91N6B 

文件结构

  1. actions包定义了struts2 action。

  2. action.results包定义了自己的struts result。此半成品用不到。

  3. aspect包将定义aop切面。此半成品用不到。

  4. auth包定义了用于SS认证的自定义类。我们将使用自己的类来查询数据库。

  5. business包定义了各种service接口以及实现。

  6. db.mapper包定义了Mybatis Dao接口。

  7. model包定义了域模型。本文中域模型只有一个User类。

  8. util包定义了工具类。本文util将提供password encode功能。

  9. applicationContext-aop.xml本文不用。

  10. applicationContext-business.xml配置service bean。

  11. applicationContext-mybatis.xml配置Spring和Mybatis的集成以及各种Dao。

  12. applicationContext-security.xml配置Spring Security。

  13. applicationContext-struts.xml配置Spring与Struts的集成以及所有的struts bean。

  14. schema.sql中定义了数据库表。

  15. log4j与struts.xml不多说。

  16. 在jsp中,本文将用到login.jsp, register.jsp以及登陆成功后可以访问到test.jsp。其它的不会用到。

  17. 在resources下面,/com/xpbug/demo/db/mybatis-config.xml定义了mybatis。

  18. 在resources下面,/com/xpbug/demo/db/mapper/UserDao.xml定义了UserDao的实现。

开发平台选用的是Eclipse+Maven+tomcat. 项目的依赖请查看pom.xml。

配置web.xml

将Spring Security filter至于struts filter之前,让SS可以多所有的URL进行保护。

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/user/*</url-pattern>
        <url-pattern>/auth/*</url-pattern>
        <url-pattern>/register/*</url-pattern>
    </filter-mapping>

配置Spring Security

让SS对/auth/login*和/register/**放行。配置Authentication-Provider使用自己定义的UserService, 并使用PasswordEncoder对password进行加密。

    <s:http use-expressions="true" authentication-manager-ref="AuthManager">
        <s:intercept-url pattern="/auth/login*" access="permitAll()" />
        <s:intercept-url pattern="/register/**" access="permitAll()" />
        <s:intercept-url pattern="/**" access="isAuthenticated()" />
        
        <s:form-login login-page='/auth/login'
            default-target-url="/user/profile" login-processing-url="/spring_security_check"
            authentication-failure-url="/auth/login?error" password-parameter="password" username-parameter="username" />

        <s:logout invalidate-session="true" logout-success-url="/auth/login?logout" logout-url="/spring_logout" />
    </s:http>

    <s:authentication-manager id="AuthManager">
        <s:authentication-provider ref="daoAuthProvider">
        </s:authentication-provider>
    </s:authentication-manager>

    <bean id="daoAuthProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="myUserAuthService" /> <!-- From business. We implement it. -->
        <property name="passwordEncoder" ref="passwordEncoder" />
    </bean>

    <bean id="myUserAuthService" class="com.xpbug.demo.auth.UserService">
        <!-- Use mybatis dao -->
        <property name="userDao" ref="UserDao"></property>
    </bean>

    <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
        <constructor-arg name="strength" value="10"></constructor-arg>
    </bean>

其中UserDao在applicationContext-mybatis.xml中有定义。

com.xpbug.demo.auth.UserService的实现为:

    public class UserService implements UserDetailsService {
        private UserDao userDao;
        private Logger logger = LoggerFactory.getLogger(UserService.class);
        
        /* (non-Javadoc)
         * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
         */
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            com.xpbug.demo.model.User user = this.userDao.getLoginById(username);
            List<String> roles = user.getRoles();
            List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
            for (String r:roles) {
                logger.info("Grant role: {}", r);
                authorities.add(new SimpleGrantedAuthority(r));
            }
            User sUser = new User(user.getUserId(), user.getPassword(), authorities);
            return sUser;
        }
	
        // Getters and Setters...
    }

在UserService中,我们使用UserDao获取数据库中的用户,然后将数据库取出的用户,封装成SS所需要的形式。

这样,登录部分完成了。接下来,我们来定义Struts的Action。

Struts

在Struts中,我将定义以下几个URI:

  1. /auth/login  展示登录页面

  2. /auth/logout  注销,然后转登录页面。

  3. /register/form  展示注册页面

  4. /register/do  处理register form POST。然后chain to auto login action.

  5. /register/autoLogin  承接/register/do, 进行自动登录,成功以后重定向到/user/profile

  6. /user/profile  一个受SS保护的页面。

struts.xml:

    <constant name="struts.action.extension" value="" />
	
    <package name="auth" extends="abstract" namespace="/auth">
        <action name="login" class="LoginPageAction">
            <result name="success">/WEB-INF/jsp/login.jsp</result>
        </action>
        <action name="logout">
            <result name="success" type="redirect">/spring_logout</result>
        </action>
    </package>
    
    <package name="register" extends="abstract" namespace="/register">
        <action name="form" class="RegisterAction">
            <result>/WEB-INF/jsp/register.jsp</result>
        </action>
        <action name="do" class="RegisterAction" method="register">
            <result name="success" type="chain">
                <param name="actionName">autoLogin</param>
                <param name="method">login</param>
            </result>
        </action>
        <action name="autoLogin" class="AutoLoginAction" method="login">
            <result type="redirect">/user/profile</result>
        </action>
    </package>
	
    <package name="user" extends="abstract" namespace="/user">
        <action name="profile">
            <result name="success">/WEB-INF/jsp/test.jsp</result>
        </action>
    </package>

其它Action不表,重点说下掌管注册和自动登录的两个Action。

RegisterAction

服务于注册的Action需要接收用户id和密码。此外,它还需要userService服务于用户创建,util服务于encode password。util的定义可以在applicationContext-business.xml中找到,它使用了Spring Security提供的password encoder,和登录时使用的encoder是同一个bean。

用户创建成功以后,将使用Chain Result,转到AutoLoginAction。

    public class RegisterAction extends ActionSupport {
        private static final long serialVersionUID = -3114254552070420296L;
	
        private UserService userService;
        private Util util;
        private String uid;
        private String password;
        private String repassword;
	
        public String register() {
            if (password.equals(repassword)) {
                User user = new User();
                user.setUserId(uid);
                user.setPassword(util.encodePassword(password));
                userService.registerUser(user);
            }
            return "success";
        }
        // Getters and Setters...
    }

AutoLoginAction

因为AutoLoginAction是由RegisterAction的result Chain过来的,所以可以接收RegisterAction相同的parameters。我们让它接收uid和password两个参数。

此外,它还需要用到登录时使用的AuthenticationManager, AuthenticationManager将会被Spring注入。

在login函数执行完毕以后,Session中就存在了SS所需要的所有认证信息。后面的URL就不需要再进行认证了。

AutoLoginAction成功以后,会重定向到/user/profile页面。

public class AutoLoginAction {
    private String uid;
    private String password;
    private AuthenticationManager authenticationManager;
	
    public String login() {
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(uid, password);
        HttpServletRequest request = ServletActionContext.getRequest();
        // generate session if one doesn't exist
        request.getSession();
        
        token.setDetails(new WebAuthenticationDetails(request));
        Authentication authenticatedUser = authenticationManager.authenticate(token);
        
        SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
        return "success";
    }
	
    // Getters and Setters ...
}

Bean注册

关于Struts, mybatis和business各类bean的注册,不多废话。可以查看源代码。

运行

请先安装mysql,然后使用schema.sql创建数据库。

在applicationContext-mybatis.xml中修改datasource的配置。

编译打包成demo.war. 直接部署到tomcat中。

可访问URL: http://localhost:8080/demo/auth/login 

© 著作权归作者所有

共有 人打赏支持
xpbug
粉丝 300
博文 97
码字总数 125336
作品 0
浦东
程序员
SpringMvc的使用

目录结构 一、SpringMvc相关知识 11、SpringMvc的大体认识 ? 12、什么是MVC ? 13、SpringMvc内部是怎么样工作的? 二、环境以及第三方技术的说明 三、我们进入正题,下边通过一个个实例来介...

丈量大地 ⋅ 2015/11/26 ⋅ 4

Shiro和Spring Security对比

Shiro简介 Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不...

有余力则学文 ⋅ 04/27 ⋅ 0

30分钟学会如何使用Shiro

一、架构 要学习如何使用Shiro必须先从它的架构谈起,作为一款安全框架Shiro的设计相当精妙。Shiro的应用不依赖任何容器,它也可以在JavaSE下使用。但是最常用的环境还是JavaEE。下面以用户登...

qq5923dd411b8fa ⋅ 2017/05/23 ⋅ 0

30分钟学会如何使用Shiro

一、架构 要学习如何使用Shiro必须先从它的架构谈起,作为一款安全框架Shiro的设计相当精妙。Shiro的应用不依赖任何容器,它也可以在JavaSE下使用。但是最常用的环境还是JavaEE。下面以用户登...

qq58edeba279279 ⋅ 2017/05/09 ⋅ 0

ZHENFENGSHISAN/perfect-ssm

Quick Start 项目简介 ssm系列 ssm-demo:Spring+SpringMVC+Mybatis+easyUI整合 perfect-ssm:RESTful API+redis缓存 ssm-cluster:前后端分离+集群部署 ssm-dubbo:dubbo服务化 ssm-micro-se......

ZHENFENGSHISAN ⋅ 2017/09/18 ⋅ 0

30分钟学会如何使用Shiro

摘要: Shiro的核心部分是SecurityManager,它负责安全认证与授权。Shiro本身已经实现了所有的细节,用户可以完全把它当做一个黑盒来使用。SecurityUtils对象,本质上就是一个工厂类似Spring中...

qq592fbb5b34ad7 ⋅ 2017/06/07 ⋅ 0

SSM整合,个人总结和step

我最近才整合完SSM。 前段时间,分开学习了这三个框架,都是看某黄埔军校的视频,整合的部分没看视频,想自己做。 但是有一些部分自己没有能完成,主要是如何从spring容器里取出Application...

wzlhlhhh ⋅ 05/11 ⋅ 0

30分钟学会如何使用Shiro

一、架构 要学习如何使用Shiro必须先从它的架构谈起,作为一款安全框架Shiro的设计相当精妙。Shiro的应用不依赖任何容器,它也可以在JavaSE下使用。但是最常用的环境还是JavaEE。下面以用户登...

park ⋅ 2017/11/28 ⋅ 0

Spring Boot 自动配置的 “魔法” 是如何实现的?

原文出处:sylvanassun Spring Boot是Spring旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准...

sylvanassun ⋅ 06/10 ⋅ 0

结合SSM框架讲解Shiro案例--Shiro Demo

本教程结合SSM(SpringMVC + Mybatis)框架讲解Shiro(Shiro是 Java 的一个安全框架。我们经常看到它被拿来和 Spring 的 Security 来对比。),讲解的内容有自定义Shiro拦截器,Shiro Freem...

8446666 ⋅ 2016/06/29 ⋅ 8

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring | IOC AOP 注解 简单使用

写在前面的话 很久没更新笔记了,有人会抱怨:小冯啊,你是不是在偷懒啊,没有学习了。老哥,真的冤枉:我觉得我自己很菜,还在努力学习呢,正在学习Vue.js做管理系统呢。即便这样,我还是不...

Wenyi_Feng ⋅ 今天 ⋅ 0

博客迁移到 https://www.jianshu.com/u/aa501451a235

博客迁移到 https://www.jianshu.com/u/aa501451a235 本博客不再更新

为为02 ⋅ 今天 ⋅ 0

win10怎么彻底关闭自动更新

win10自带的更新每天都很多,每一次下载都要占用大量网络,而且安装要等得时间也蛮久的。 工具/原料 Win10 方法/步骤 单击左下角开始菜单点击设置图标进入设置界面 在设置窗口中输入“服务”...

阿K1225 ⋅ 今天 ⋅ 0

Elasticsearch 6.3.0 SQL功能使用案例分享

The best elasticsearch highlevel java rest api-----bboss Elasticsearch 6.3.0 官方新推出的SQL检索插件非常不错,本文一个实际案例来介绍其使用方法。 1.代码中的sql检索 @Testpu...

bboss ⋅ 今天 ⋅ 0

informix数据库在linux中的安装以及用java/c/c++访问

一、安装前准备 安装JDK(略) 到IBM官网上下载informix软件:iif.12.10.FC9DE.linux-x86_64.tar放在某个大家都可以访问的目录比如:/mypkg,并解压到该目录下。 我也放到了百度云和天翼云上...

wangxuwei ⋅ 今天 ⋅ 0

PHP语言系统ZBLOG或许无法重现月光博客的闪耀历史[图]

最近在写博客,希望通过自己努力打造一个优秀的教育类主题博客,名动江湖,但是问题来了,现在写博客还有前途吗?面对强大的自媒体站点围剿,还有信心和可能型吗? 至于程序部分,我选择了P...

原创小博客 ⋅ 今天 ⋅ 0

IntelliJ IDEA 2018.1新特性

工欲善其事必先利其器,如果有一款IDE可以让你更高效地专注于开发以及源码阅读,为什么不试一试? 本文转载自:netty技术内幕 3月27日,jetbrains正式发布期待已久的IntelliJ IDEA 2018.1,再...

Romane ⋅ 今天 ⋅ 0

浅谈设计模式之工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻...

佛系程序猿灬 ⋅ 今天 ⋅ 0

Dockerfile基础命令总结

FROM 指定使用的基础base image FROM scratch # 制作base image ,不使用任何基础imageFROM centos # 使用base imageFROM ubuntu:14.04 尽量使用官方的base image,为了安全 LABEL 描述作...

ExtreU ⋅ 昨天 ⋅ 0

存储,对比私有云和公有云的不同

导读 说起公共存储,很难不与后网络公司时代的选择性外包联系起来,但尽管如此,它还是具备着简单和固有的可用性。公共存储的名字听起来也缺乏专有性,很像是把东西直接堆放在那里而不会得到...

问题终结者 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部