由于第一次使用SpringSecurity,经过研究学习,总结了以下操作步骤:
- 加载spring security扩展
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
- 写sping security 的配置文件SecurityConfig.java
package com.htcasting.common.config;
import com.htcasting.common.handle.AuthenticationEntryPointImpl;
import com.htcasting.common.handle.LogoutSuccessHandleImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private AuthenticationEntryPointImpl unauthorizedHandler;
@Autowired
private LogoutSuccessHandleImpl logoutSuccessHandle;
/**
* 解决 AuthenticationManager 无法直接注入问题
* @return
* @throws Exception
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
// 认证失败处理类
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 基于token 所以不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求
.authorizeRequests()
// 对于login请求允许匿名访问
.antMatchers("/login").anonymous()
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js"
).permitAll()
// 除了上面的请求外都需要鉴权认证
.anyRequest().authenticated()
.and()
.headers().frameOptions().disable();
// 退出成功跳转地址以及退出成功处理类
http.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandle);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
}
- 写用户实体类 实现 UserDetails接口
package com.htcasting.common.entry.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.htcasting.common.entry.SysUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.Set;
public class LoginUser implements UserDetails {
private static final long serialVersionUID = 2427417409609127686L;
private Long id;
private String userName;
private Long deptId;
private String token;
private Set<String> permissions;
private SysUser user;
public LoginUser() {
}
public LoginUser(Set<String> permissions, SysUser user) {
this.permissions = permissions;
this.user = user;
}
public LoginUser(Long id, Long deptId, SysUser user, Set<String> permissions) {
this.id = id;
this.deptId = deptId;
this.permissions = permissions;
this.user = user;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public Set<String> getPermissions() {
return permissions;
}
public void setPermissions(Set<String> permissions) {
this.permissions = permissions;
}
public SysUser getUser() {
return user;
}
public void setUser(SysUser user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@JsonIgnore
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUserName();
}
/**
* 账户是否未过期,过期无法验证
*/
@JsonIgnore
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* 指定用户是否解锁,锁定的用户无法进行身份验证
*
* @return
*/
@JsonIgnore
@Override
public boolean isAccountNonLocked() {
return true;
}
/**
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
*
* @return
*/
@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 是否可用 ,禁用的用户不能身份验证
*
* @return
*/
@JsonIgnore
@Override
public boolean isEnabled() {
return true;
}
}
- 写UserDetailsService 的实现类UserDetailsServiceImpl
package com.htcasting.common.service;
import com.htcasting.common.entry.SysUser;
import com.htcasting.common.entry.model.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
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;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private SysUserService userService;
@Autowired
private SysPermissionService sysPermissionService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser user = userService.findUserByUserName(username);
UserDetails loginUser = createLoginUser(user);
return loginUser;
}
private UserDetails createLoginUser(SysUser user) {
return new LoginUser(user.getId(),user.getDeptId(),user,sysPermissionService.getMenuPermission(user));
}
}
- 登录 验证
package com.htcasting.common.service;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class LoginService {
@Resource // 此处只能使用@Resource注入不能使用@Autowired
private AuthenticationManager authenticationManager;
public String login(String username, String password) {
Authentication authentication = null;
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
try {
authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username,password));
} catch (Exception e) {
System.out.println(e);
}
return "123";
}
}