1. 程式人生 > >spring security的簡單應用

spring security的簡單應用

location factory wire contex 頁面 pub users 成功 locked

本文只包涵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 {
    }

}

spring security的簡單應用