spring security的简单应用

本文只包涵spring security配置部分,不是一个完整项目,不过可以任意添加到一个web项目中,不需要对原来的程序做任何修改

部分内容来源于网络,如有雷同,毫无意外

 

1、xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
http://www.springframework.org/schema/security   
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
    <global-method-security pre-post-annotations="enabled">
    </global-method-security>
    
    <!-- 不拦截的路径 -->
    <http pattern="/registerPage" security="none" />
    <http pattern="/mainPage" security="none"></http>
    <http pattern="/item/itemid**" security="none"></http>
    <http pattern="/css/**" security="none" />
    <http pattern="/font/**" security="none" />
    <http pattern="/images/**" security="none" />
    <http pattern="/js/**" security="none" />
    
    <http auto-config="true">
        <!-- 登录配置 -->
        <form-login login-page="/loginPage"
            authentication-failure-url="/login/failure"
            login-processing-url="/login" 
            authentication-success-handler-ref="mySuccessHandler"  
            username-parameter="username"
            password-parameter="password" />

        <!-- 用户登出 -->
        <logout invalidate-session="true" logout-success-url="/loginPage"
            logout-url="/logout" />
            
        <!-- 拦截页面 -->    
        <intercept-url pattern="/item/**" access="ROLE_USER" />
        <intercept-url pattern="/admin/**" access="ROLE_USER" />
    </http>
    
    <!-- 登录成功的处理方法 -->
    <beans:bean id="mySuccessHandler" class="security.LoginSuccessHandle" ></beans:bean>
    
    <!-- 获取UserDettail的bean -->
    <beans:bean id="UserDetailService" class="security.MyUserDetailService"></beans:bean>
    
    <!-- 在这里也是一个大坑,查询网上的文章,这里都是引用的实现了UserDetailsService的类 -->
    <beans:bean id="UserService" class="security.SecurityProvider"></beans:bean>
    <authentication-manager>
        <authentication-provider ref="UserService">
        </authentication-provider>
    </authentication-manager>
</beans:beans>

 

2、用户权限信息类

省略相关数据库代码以及dao层代码

package po;

public class UserRole {

    private String username;
    private String password;
    private String role;

    public UserRole(String username, String password, String role) {
        super();
        this.username = username;
        this.password = password;
        this.role = role;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}

 

3、MyUserDetail类,实现UserDetail接口,包含用户信息和用户权限类型

package security;

import java.util.Collection;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import po.UserRole;

public class MyUserDetail implements UserDetails {
    /**
     * 
     */
    private static final long serialVersionUID = -5619502406659516775L;
    private UserRole myUser;
    private Collection<? extends GrantedAuthority> authorities;

    public MyUserDetail(UserRole user,Collection<? extends GrantedAuthority> authorities) {
        this.myUser = user;
        this.authorities = authorities;
    }

    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }
    public UserRole getMyUser() {
        return myUser;
    }
    public String getPassword() {
        return myUser.getPassword();
    }

    public String getUsername() {
        return myUser.getUsername();
    }

    public boolean isAccountNonExpired() {
        return false;
    }

    public boolean isAccountNonLocked() {
        return false;
    }

    public boolean isCredentialsNonExpired() {
        return false;
    }

    public boolean isEnabled() {
        return false;
    }

}

 

4、MyUserDetailService类,实现UserDetailsService接口,用来获取一个UserDetail对象

package security;

import java.util.ArrayList;
import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import mapper.UserRoleMapper;
import po.UserRole;

@Service
public class MyUserDetailService implements UserDetailsService  {
    @Autowired
    UserRoleMapper userdao;
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        UserRole user =userdao.getUserByName(username);
        if(user==null)
        {
            throw new  UsernameNotFoundException("找不到该用户");
        }
//        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
//        SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role);
//        grantedAuthorities.add(grantedAuthority);
        return new MyUserDetail(user, getAuthorities(user.getRole()));
    }

    private Collection<GrantedAuthority> getAuthorities(String role) {
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
        SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role);
        grantedAuthorities.add(grantedAuthority);
        return grantedAuthorities;
    }

}

 

5、SecurityProvider类,实现了AuthenticationProvider,返回一个UsernamePasswordAuthenticationToken

package security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class SecurityProvider implements AuthenticationProvider {
    @Autowired
    private MyUserDetailService userDetailsService;
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
        UserDetails userDetails = userDetailsService.loadUserByUsername(token.getName());
        if (userDetails == null) {
            throw new UsernameNotFoundException("找不到该用户");
        }
        if(!userDetails.getPassword().equals(token.getCredentials().toString()))
        {
              throw new BadCredentialsException("用户密码错误");
        }
        return new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(),userDetails.getAuthorities());
    }

    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.equals(authentication);
    }

}

 

 6、登录成功后自定义处理过程

spring security可以在配置文件中设置登录成功后的跳转页面,或者是直接返回认证前想要访问的页面,但是因为有时候用户是使用ajax请求登录,所以需要自定义一些操作,我是在登录成功后跳转到控制层url,

在url中携带需要跳转的参数,然后在控制层中将url参数返回到ajax,再由前端重新请求控制层跳转

package security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;

public class LoginSuccessHandle implements AuthenticationSuccessHandler, InitializingBean {
    private RequestCache requestCache = new HttpSessionRequestCache();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authen)
            throws IOException, ServletException {
        SavedRequest savedRequest = requestCache.getRequest(request, response);
        // 默认认证后跳转路径
        String targetUrl = "/mainPage";

        // 如果登录前有请求为拦截页面,则验证后跳转到该页面
        if (savedRequest != null) {
            targetUrl = savedRequest.getRedirectUrl();
        }

        // 跳转到认证成功处理控制器
        response.sendRedirect("/loginSuccess?url=" + targetUrl);

    }

    @Override
    public void afterPropertiesSet() throws Exception {
    }

}

 

posted @ 2018-01-10 12:07  周李科的博客  阅读(479)  评论(0编辑  收藏  举报