文档章节

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

xpbug
 xpbug
发布于 2014/11/14 18:07
字数 1426
阅读 1098
收藏 3

源码

下载

半成品源码下载地址: 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
博文 102
码字总数 125336
作品 0
浦东
程序员
SpringCloud(第 051 篇)EurekaServer集群高可用注册中心以及简单的安全认证

SpringCloud(第 051 篇)EurekaServer集群高可用注册中心以及简单的安全认证 - 一、大致介绍 二、实现步骤 2.1 添加 maven 引用包 2.2 添加应用默认配置文件(springms-discovery-eureka-h...

HMILYYLIMH
2017/10/25
0
0
Spring 系列,第 3 部分: 进入 Spring MVC

在 Spring 系列 的第 3 部分中,我介绍 Spring MVC 框架。就像在以前的文章中一样,我用银行示例介绍如何建模和构建简单的应用程序。示例应用程序包含了已经学过的一些技术(例如依赖注入),...

qq58edf1d989a2d
06/26
0
0
30分钟学会如何使用Shiro

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

qq58edeba279279
06/26
0
0
更加优雅地配置Spring Securiy(使用Java配置和注解)

Spring Security 借助一系列Servlet Filter 来提供安全性功能,但是借助Spring的小技巧,我们只需要配置一个Filer就可以了,DelegatingFilterProxy是一个特殊的Servlet Filter,它本身所做的...

小小庄
2016/10/14
0
0
SpringMvc的使用

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

丈量大地
2015/11/26
531
4

没有更多内容

加载失败,请刷新页面

加载更多

下一页

bat强制启用宏

运行bat文件后,将宏的安全等级设为低,达到启用宏的目的。 REM 这个文件将提供用户快速设置Excel宏的安全等级@ECHO OFFCLS:cmd4REG ADD "HKEY_CURRENT_USER\Software\Mi...

tedzheng
5分钟前
0
0
流,用声明性的方式处理数据集 - 读《Java 8实战》

引入流 Stream API的代码 声明性 更简洁,更易读 可复合 更灵活 可并行 性能更好 流是什么? 它允许以声明方式处理数据集合 遍历数据集的高级迭代器 透明地并行处理 简短定义:从支持数据处理...

yysue
7分钟前
0
0
postman发送json格式的post请求

postman发送json格式的post请求 在地址栏里输入请求url:http://127.0.0.1:8081/getmoney 选择“POST”方式, 在“headers”添加key:Content-Type , value:application/json 点击"body",''ra...

两广总督bogang
14分钟前
0
0
Javascript将html转成pdf,下载(html2canvas 和 jsPDF)

最近碰到个需求,需要把当前页面生成pdf,并下载。弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :) 项目源码地址:https://github.com/linwalker/render-html-to-pdf html2ca...

孟飞阳
14分钟前
0
0
pureftp源码编译及设定

--- use for RHEL 567 and Ubuntu 1604 1. download pureftpd wget http://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.47.tar.bz2 2. install gcc #apt-get install -y li......

zzimac
16分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部