文档章节

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

xpbug
 xpbug
发布于 2014/11/14 18:07
字数 1426
阅读 1185
收藏 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
粉丝 303
博文 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 Boot极简教程》第16章 Spring Boot安全集成Spring Security

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

程序员诗人
2017/04/17
0
0
spring+springMVC+mybatis的整合 part6

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

ben4
2017/07/18
0
0
一步步开发 Spring MVC 应用

Spring MVC 框架 Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还是 Struts 这样的 Web 框架。通过策略接口...

justjavac
2013/02/23
803
1
Spring 系列,第 3 部分: 进入 Spring MVC

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

qq58edf1d989a2d
06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

C4C销售订单行项目价格维护方法

需求很简单,能够创建销售订单,在行项目里添加产品,带出价格来,同时把总价显示在销售订单抬头区域。 如下图所示: 下面是具体配置。 Business Configuration里,点击Sales Order的配置: ...

JerryWang_SAP
31分钟前
6
0
deepin中配置robot framework环境

本文永久更新地址:https://my.oschina.net/bysu/blog/2989005 【若要到岸,请摇船:开源中国 不最醉不龟归】 1.在终端中输入pip,回车,如果提示没有该命令,则先安转pip sudo apt-get inst...

不最醉不龟归
今天
8
0
OSChina 周日乱弹 —— 钱不还,我就当你人不在了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享Bigleaf的单曲《小鹿》 《小鹿》- Bigleaf 手机党少年们想听歌,请使劲儿戳(这里) 周日在家做什么? 做手工呀, @poorfis...

小小编辑
今天
192
5
EOS docker开发环境

使用eos docker镜像是部署本地EOS开发环境的最轻松愉快的方法。使用官方提供的eos docker镜像,你可以快速建立一个eos开发环境,可以迅速启动开发节点和钱包服务器、创建账户、编写智能合约....

汇智网教程
今天
22
0
《唐史原来超有趣》的读后感优秀范文3700字

《唐史原来超有趣》的读后感优秀范文3700字: 作者:花若离。我今天分享的内容《唐史原来超有趣》这本书的读后感,我将这本书看了一遍之后就束之高阁了,不过里面的内容一直在在脑海中回放,...

原创小博客
今天
33
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部