1. 程式人生 > >Spring security 4 使用java註解進行登陸驗證

Spring security 4 使用java註解進行登陸驗證

本文只作為spring官方文件的補充,不會解釋spring以及hibernate的具體技術細節。
本文預設專案已經具有相關的使用者表和DAO,現在我們以此為基礎進行基本的使用者登陸認證,url許可權管理和登出設定。
網上有很多文件描述瞭如何為專案新增spring security支援。在spring boot中,我們只需要添加了配置類,就可以描述spring security的控制資訊:

package edu.nju.web.security;

import org.springframework.security.core.userdetails.UserDetailsService;
import
org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.StandardPasswordEncoder; import
javax.annotation.Resource; /** * Http security config * @author cuiods */ @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Resource private UserDetailsService userService; @Resource private SuccessHandler successHandler; @Resource public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ auth .userDetailsService(userService) .passwordEncoder(standardEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .antMatchers("/api/admin/**").access("hasRole('admin')") .and() .formLogin() .loginPage("/login") .successHandler(successHandler) .permitAll() .and() .logout() .logoutUrl("/login?logout") .invalidateHttpSession(true) .deleteCookies("JSESSIONID") .permitAll() .and() .csrf(); } /** * standard password encoder: SHA-256 * @return {@link PasswordEncoder} */ @Bean public PasswordEncoder standardEncoder() { return new StandardPasswordEncoder(); } }

在這個類中配置了URL對應的許可權,登陸和登出對應的頁面(spring security自帶登陸頁面,預設為/login,登出為/login?logout,具體可以檢視官方文件)。
以上的程式碼的UserDetailsService是重點,UserDetailsService是一個介面,實現該介面可以定義從資料庫取出的使用者名稱、密碼、許可權等資訊。有了這些資訊,spring security可以自動進行密碼驗證和許可權管理。

package edu.nju.bl.serviceImpl;

import edu.nju.data.dao.UserDao;
import edu.nju.data.entity.User;
import org.springframework.security.core.userdetails.UserDetailsService;
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.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * person service impl
 */
@Service
public class UserServiceImpl implements UserDetailsService {

    @Resource
    private UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userDao.findByUsername(username);
        if (user==null) {
            throw new UsernameNotFoundException("Cannot find user!");
        }
        Set<GrantedAuthority> authorities = new HashSet<>();
        authorities.add(new SimpleGrantedAuthority(user.getType().toString()));
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>(authorities);
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                true,true,true,true,grantedAuthorities);
    }
}

將使用者資訊取出並封裝成org.springframework.security.core.userdetails.User類(UserDetails的實現類),在上面的配置類中進行配置,spring就會自己管理使用者的密碼驗證,並判斷使用者所處的角色。

另外,上面還提到了SuccessHandler,該類設定了登陸成功後的跳轉介面。

package edu.nju.web.security;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

/**
 * login success handler
 * @author cuiods
 */
@Component
public class SuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException {
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        String targetUrl = "";
        if (authorities.contains("admin")) {
            targetUrl = "/admin";
        } else if (authorities.contains("teacher")) {
            targetUrl = "/teacher";
        } else {
            targetUrl  ="/student";
        }
        redirectStrategy.sendRedirect(request,response,targetUrl);
    }
}

目前網上介紹的資料更多以簡單的描述性示例為主。本文只是介紹了spring security的一個簡單場景的應用,要全面瞭解spring security的相關內容,可以參見網上的官網文件和其他資料。