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

本文的原文连接是: 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下载源代码,解压缩导入工程。
spring security 安全框架remember me,demo学习_第1张图片
代码很简单,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里面已经介绍的非常清楚了。
spring security 安全框架remember me,demo学习_第2张图片
使用remember me登陆之后会有一个cookie。
spring security 安全框架remember me,demo学习_第3张图片
当退出之后就没了。
当没用权限的时候返回403。
spring security 安全框架remember me,demo学习_第4张图片

配置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换用户登陆名,在用户登录名查询用户信息,权限。
spring security 安全框架remember me,demo学习_第5张图片

但是在做互联网应用的时候,一般用户就一个权限。根本没用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改名字的问题,还需要继续研究。

你可能感兴趣的:(spring,Security)