文档章节

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

xpbug
 xpbug
发布于 2014/11/14 18:07
字数 1426
阅读 1137
收藏 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
粉丝 302
博文 102
码字总数 125336
作品 0
浦东
程序员
《Spring Boot极简教程》第16章 Spring Boot安全集成Spring Security

第16章 Spring Boot安全集成Spring Security 开发Web应用,对页面的安全控制通常是必须的。比如:对于没有访问权限的用户需要转到登录表单页面。要实现访问控制的方法多种多样,可以通过Aop...

程序员诗人
2017/04/17
0
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
spring+springMVC+mybatis的整合 part6

登录注册 首先,我们webapp要实现用户登录,必须得能新建用户。所以先把注册用户放在前面。 预期功能:打开注册页面 填写注册信息 点击注册 显示注册后的提示信息 一个web注册页面 web页面能...

ben4
2017/07/18
0
0
30分钟学会如何使用Shiro

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

qq58edeba279279
06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

WinDbg

参考来自:http://www.cnit.net.cn/?id=225 SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols ctrl + d to open dump_file Microsoft (R) Windows Debugger Version 6.12.0002.633......

xueyuse0012
今天
2
0
OSChina 周五乱弹 —— 想不想把92年的萝莉退货

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @罗马的王:分享松澤由美的单曲《地球ぎ》 很久没看圣斗士星矢了 《地球ぎ》- 松澤由美 手机党少年们想听歌,请使劲儿戳(这里) @开源中国首...

小小编辑
今天
14
2
springBoot条件配置

本篇介绍下,如何通过springboot的条件配置,控制Bean的创建 介绍下开发环境 JDK版本1.8 springboot版本是1.5.2 开发工具为 intellij idea(2018.2) 开发环境为 15款MacBook Pro 前言 很多时候,...

贺小五
今天
1
0
javascript source map 的使用

之前发现VS.NET会为压缩的js文添加一个与文件名同名的.map文件,一直没有搞懂他是用来做什么的,直接删除掉运行时浏览器又会报错,后来google了一直才真正搞懂了这个小小的map文件背后的巨大...

粒子数反转
昨天
1
0
谈谈如何学Linux和它在如今社会的影响

昨天,还在农耕脑力社会,今天已经人工智能技术、大数据、信息技术的科技社会了,高速开展并迅速浸透到当今科技社会的各个方面,Linux日益成为人们信息时代的到来,更加考验我们对信息的处理程...

linux-tao
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部