对于spring Security要有一个主要的配置类。
其配置都放在下面了(完整版)
`package com.cun.security3.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class SpringSecurityConf extends WebSecurityConfigurerAdapter {
@Autowired
AjaxAuthenticationEntryPoint authenticationEntryPoint; // 未登陆时返回 JSON 格式的数据给前端(否则为 html)
@Autowired
AjaxAuthenticationSuccessHandler authenticationSuccessHandler; // 登录成功返回的 JSON 格式数据给前端(否则为 html)
@Autowired
AjaxAuthenticationFailureHandler authenticationFailureHandler; // 登录失败返回的 JSON 格式数据给前端(否则为 html)
@Autowired
AjaxLogoutSuccessHandler logoutSuccessHandler; // 注销成功返回的 JSON 格式数据给前端(否则为 登录时的 html)
@Autowired
AjaxAccessDeniedHandler accessDeniedHandler; // 无权访问返回的 JSON 格式数据给前端(否则为 403 html 页面)
@Autowired
SelfUserDetailsService userDetailsService; // 自定义user
@Autowired
JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; // JWT 拦截器
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 加入自定义的安全认证
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 去掉 CSRF
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 使用 JWT,关闭token
.and()
.httpBasic().authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.anyRequest()
.access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
.and()
.formLogin() //开启登录
/**
可以在这里修改登录接口.loginProcessUrl()
**/
.successHandler(authenticationSuccessHandler) // 登录成功
.failureHandler(authenticationFailureHandler) // 登录失败
.permitAll()
.and()
.logout()
.logoutSuccessHandler(logoutSuccessHandler)
.permitAll();
// 记住我
http.rememberMe().rememberMeParameter("remember-me")
.userDetailsService(userDetailsService).tokenValiditySeconds(300);
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); // 无权访问 JSON 格式的数据
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); // JWT Filter
}
}
`
当然主配置类有了也需要其他的东西,由于一条条列出来比较麻烦逻辑混乱,我就直接按照登录流程来配置文件。
--------------------当你登录的时候就会从loginProcessUrl(“你自己定义的login接口”)或者默认的/login,进入程序。说到底,spring security本质上就是一条过滤链。你要做的就是把它提供给你的interface接口实现了,重写里面的方法来实现过滤功能。所以第一个实现的就是UserDetialService,它里面有个方法叫做loadUserByUserName(String username)
你可以在这个方法里面查询数据库通过username(这个就是你登录时候传过来的username),来判断登录操作。值得注意的是,你的数据库里面的password如果是加密的话,这里可以不做处理,如果是明文的话(不推荐,会有风险)就需要在这里进行加密,因为spring Security要求登录的时候你传过来的password加密,所以你密码传上去的时候是与加密后的密码对比。
最后返回类型是UserDetial,你可以写一个自己的类继承它然后返回。当然也可以用spring security自带的User,User可以传三个构造或者全部。三个的分别是用户名,密码,权限Set。
package com.cun.security3.config;
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.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.Set;
@Component
public class SelfUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//构建用户信息的逻辑(取数据库/LDAP等用户信息)
SelfUserDetails userInfo = new SelfUserDetails();
userInfo.setUsername(username);
userInfo.setPassword(new BCryptPasswordEncoder().encode("123"));
Set authoritiesSet = new HashSet();
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_ADMIN");
authoritiesSet.add(authority);
userInfo.setAuthorities(authoritiesSet);
return userInfo;
}
}
package com.cun.security3.config;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
/**
* ① 定义 user 对象
*/
public class SelfUserDetails implements UserDetails, Serializable {
private String username;
private String password;
private Set<? extends GrantedAuthority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
public void setAuthorities(Set<? extends GrantedAuthority> authorities) {
this.authorities = authorities;
}
@Override
public String getPassword() { // 最重点Ⅰ
return this.password;
}
@Override
public String getUsername() { // 最重点Ⅱ
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}