Spring security 4 使用java註解進行登陸驗證
阿新 • • 發佈:2019-01-31
本文只作為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的相關內容,可以參見網上的官網文件和其他資料。