spring security 安全框架remember me,demo学习

来源:互联网 发布:js offsetwidth 错误 编辑:程序博客网 时间:2024/05/22 04:55

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/50018001未经博主允许不得转载。
博主地址是:http://blog.csdn.net/freewebsys

1,spring security

Spring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架。

在安全框架这边使用最多的就是spring security。
论坛资料比较充实。

一个哥们写的例子,使用用的spring secuirty3开发的。
http://www.mkyong.com/spring-security/spring-security-remember-me-example/

spring security 相关内容:
http://www.mkyong.com/tutorials/spring-security-tutorials/

官方api:
http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity.html

首先根据demo下载源代码,解压缩导入工程。

代码很简单,4个jsp文件,一个controller。
数据库使用mysql,创建数据库和表:

CREATE  TABLE users (  username VARCHAR(45) NOT NULL ,  password VARCHAR(45) NOT NULL ,  enabled TINYINT NOT NULL DEFAULT 1 ,  PRIMARY KEY (username));CREATE TABLE user_roles (  user_role_id int(11) NOT NULL AUTO_INCREMENT,  username varchar(45) NOT NULL,  role varchar(45) NOT NULL,  PRIMARY KEY (user_role_id),  UNIQUE KEY uni_username_role (role,username),  KEY fk_username_idx (username),  CONSTRAINT fk_username FOREIGN KEY (username) REFERENCES users (username));INSERT INTO users(username,password,enabled)VALUES ('mkyong','123456', true);INSERT INTO users(username,password,enabled)VALUES ('alex','123456', true);INSERT INTO user_roles (username, role)VALUES ('mkyong', 'ROLE_USER');INSERT INTO user_roles (username, role)VALUES ('mkyong', 'ROLE_ADMIN');INSERT INTO user_roles (username, role)VALUES ('alex', 'ROLE_USER');CREATE TABLE persistent_logins (    username varchar(64) not null,    series varchar(64) not null,    token varchar(64) not null,    last_used timestamp not null,    PRIMARY KEY (series));

其中persistent_logins 是记录用户remember me的。
使用token换用户名。
具体运行的效果,在那个demo里面已经介绍的非常清楚了。

使用remember me登陆之后会有一个cookie。

当退出之后就没了。
当没用权限的时候返回403。

配置authentication-manager

<authentication-manager>        <authentication-provider>            <jdbc-user-service data-source-ref="dataSource"                users-by-username-query="select username,password, enabled from users where username=?"                authorities-by-username-query="select username, role from user_roles where username =?  " />        </authentication-provider>    </authentication-manager>

首先配置了数据源,按用户名密码查询表users,查询再按照和用户名查询权限。返回权限列表。
当时remember me情况登陆的时候直接查询persistent_logins,用token换用户登陆名,在用户登录名查询用户信息,权限。

但是在做互联网应用的时候,一般用户就一个权限。根本没用role表,不用这么复杂。

3,自定义AuthenticationProvider

首先实现一个UserDetailsService。这里应该进行数据库查询。然后返回UserDetails。这里省略直接创建一个对象,密码写死,只要是登陆成功兜风返回ROLE_USER权限。

public class MyUserDetailsService implements UserDetailsService {    @Override    public UserDetails loadUserByUsername(String userName)            throws UsernameNotFoundException {        ArrayList list = new ArrayList();        list.add(new SimpleGrantedAuthority("ROLE_USER"));        User details = new User("demo", "demo", list);        return details;    }}

然后实现一个AuthenticationProvider

public class MyAuthenticationProvider implements AuthenticationProvider {    @Autowired    UserDetailsService userDetailsService;    public Authentication authenticate(Authentication authentication)            throws AuthenticationException {        //username        System.out.println("user name: " + authentication.getName());        //password        System.out.println("password: " + authentication.getCredentials());        System.out.println("getPrincipal: " + authentication.getPrincipal());        System.out.println("getAuthorities: " + authentication.getAuthorities());        System.out.println("getDetails: " + authentication.getDetails());        UserDetails userDetails = (UserDetails) this.userDetailsService.loadUserByUsername(authentication.getName());        if (userDetails != null && userDetails.getPassword() != null                && !userDetails.getPassword().equals(authentication.getCredentials())) {            //如果密码不相同直接抛出异常。            throw new UserNamePasswordErrorException("用户名或密码错!");        }        //如果用户名密码正确。        UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(                userDetails, authentication.getCredentials(), userDetails.getAuthorities());        return result;    }    public boolean supports(Class authentication) {        return true;    }    public void setUserDetailsService(UserDetailsService userDetailsService) {        this.userDetailsService = userDetailsService;    }}

这里如果用户名密码错误,直接抛出一个自定义异常:

public class UserNamePasswordErrorException extends AuthenticationException {    public UserNamePasswordErrorException(String msg) {        super(msg);    }}

然后修改配置:

    <bean id="userDetailsService" class="com.demo.security.auth.MyUserDetailsService"/>    <bean id="myAuthenticationProvider" class="com.demo.security.auth.MyAuthenticationProvider">        <property name="userDetailsService" ref="userDetailsService"/>    </bean><authentication-manager>        <authentication-provider ref="myAuthenticationProvider">        </authentication-provider>    </authentication-manager>

4,总结

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/50018001未经博主允许不得转载。
博主地址是:http://blog.csdn.net/freewebsys

spring security在安全上面只要配置下就好了,很方便。
但只是进行了初步的研究。比如加密问题,比如cookie改名字的问题,还需要继续研究。

0 0
原创粉丝点击