springboot整合springsecurity
SpringSecurity
准备工作
引入依赖
代码语言:javascript复制 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
service层
代码语言:javascript复制package com.xiaow.service;
import com.xiaow.entity.PermissionEntity;
import com.xiaow.entity.UserEntity;
import com.xiaow.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
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.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName MemberUserDetailsService
* @Author xiaow
* @Version V1.0
**/
@Component
@Slf4j
public class MemberUserDetailsService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
/**
* loadUserByUserName
*
* @param username
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 1.根据该用户名称查询在数据库中是否存在
UserEntity userEntity = userMapper.findByUsername(username);
if (userEntity == null) {
return null;
}
// 2.查询对应的用户权限
List<PermissionEntity> listPermission = userMapper.findPermissionByUsername(username);
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
listPermission.forEach(user -> {
authorities.add(new SimpleGrantedAuthority(user.getPermTag()));
});
// 3.将该权限添加到security
userEntity.setAuthorities(authorities);
return userEntity;
}
public static void main(String[] args) {
// UserDetailsService userDetailsService = (username) -> {
// return null;
// };
}
}
springsecurity-basic验证方式
这种方式弹出一个类似于alert弹出的框进行账户的登录
需要一个config类
代码语言:javascript复制package com.cyb.mobile.config;
import lombok.NoArgsConstructor;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;
@Component
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 新增security账户
* */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("xiaow").password("123").authorities("/");
}
/**
* 配置验证的方式
* */
@Override
protected void configure(HttpSecurity http) throws Exception {
//配置认证方式
http.authorizeRequests().antMatchers("/**")
.fullyAuthenticated()
.and()
.httpBasic(); //配置为basic认证
}
@Bean
public static NoOpPasswordEncoder noOpPasswordEncoder(){
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
}
springsecurity-form表单模式
代码语言:javascript复制package com.cyb.mobile.config;
import lombok.NoArgsConstructor;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;
@Component
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 新增security账户
* */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("xiaow").password("123").authorities("/");
}
/**
* 配置验证的方式
* */
@Override
protected void configure(HttpSecurity http) throws Exception {
//配置认证方式
http.authorizeRequests().antMatchers("/**")
.fullyAuthenticated()
.and()
.formLogin(); //配置为form认证 唯一修改的位置
}
@Bean
public static NoOpPasswordEncoder noOpPasswordEncoder(){
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
}
静态配置权限
使用角色来配置权限
代码语言:javascript复制package com.cyb.mobile.config;
import lombok.NoArgsConstructor;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;
@Component
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 新增security账户
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("xiaow").password("123").authorities("admin").and()
// authorities("","","")多个角色以,分割
.withUser("dw").password("123").authorities("student");
}
/**
* 配置验证的方式
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//配置认证方式
http.authorizeRequests()
// 配置端口权限
// 由角色来限定权限
.antMatchers("/user/*").hasAnyAuthority("admin")
.antMatchers("/blog/*").hasAnyAuthority("student")
.antMatchers("/**")
.fullyAuthenticated()
.and()
.formLogin(); //配置为basic认证
}
@Bean
public static NoOpPasswordEncoder noOpPasswordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
}
修改权限不足页面
进行配置错误页面
代码语言:javascript复制@Configuration
public class WebServerConfig {
@Bean
public ConfigurableServletWebServerFactory webServerFactory(){
TomcatServletWebServerFactory factory=new TomcatServletWebServerFactory();
ErrorPage errorPage400=new ErrorPage(HttpStatus.BAD_REQUEST,"/error/400.html");
ErrorPage errorPage401=new ErrorPage(HttpStatus.UNAUTHORIZED,"/error/401.html");
ErrorPage errorPage403=new ErrorPage(HttpStatus.FORBIDDEN,"/error/403.html");
ErrorPage errorPage404=new ErrorPage(HttpStatus.NOT_FOUND,"/error/404.html");
ErrorPage errorPage415=new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE,"/error/415.html");
ErrorPage errorPage500=new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,"/error/500.html");
factory.addErrorPages(errorPage400,errorPage401,errorPage403,errorPage404,errorPage415,errorPage500);
return factory;
}
}
自定义登陆页面
代码语言:javascript复制 @Override
protected void configure(HttpSecurity http) throws Exception {
//配置认证方式
http.authorizeRequests()
// 配置端口权限
// 由角色来限定权限
.antMatchers("/user/*").hasAnyAuthority("admin")
.antMatchers("/blog/*").hasAnyAuthority("student")
.antMatchers("/login.html").permitAll() //允许所有人访问该页面
.antMatchers("/**")
.fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login.html").loginProcessingUrl("/login").permitAll() //配置login为都可以访问
.and().csrf().disable();
}
动态为资源添加权限
代码语言:javascript复制 @Override
protected void configure(HttpSecurity http) throws Exception {
//配置认证方式
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry =
http.authorizeRequests();
List<Permissions> list = permissionsService.list();
list.forEach(p->{
expressionInterceptUrlRegistry.antMatchers(p.getUrl()).hasAnyAuthority(p.getPermissions());
});
expressionInterceptUrlRegistry
.antMatchers("/login.html").permitAll()//允许所有人访问该页面
.antMatchers("/**").fullyAuthenticated().and()
.formLogin()
.loginPage("/login.html").loginProcessingUrl("/login").permitAll() //配置login为都可以访问
.and().csrf().disable();
}
使用memberService来验证用户id和密码以及获取权限
代码语言:javascript复制 @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// // 设置用户账号信息和权限
// auth.inMemoryAuthentication().withUser("mayikt_admin").password("mayikt")
// .authorities("addMember", "delMember", "updateMember", "showMember");
// // 如果mayikt_admin账户权限的情况 所有的接口都可以访问,如果mayikt_add 只能访问addMember
// auth.inMemoryAuthentication().withUser("mayikt_add").password("mayikt")
// .authorities("addMember");
auth.userDetailsService(memberUserDetailsService).passwordEncoder(new PasswordEncoder() {
/**
* 对密码MD5
* @param rawPassword
* @return
*/
@Override
public String encode(CharSequence rawPassword) {
return MD5Util.encode((String) rawPassword);
}
/**
* rawPassword 用户输入的密码
* encodedPassword 数据库DB的密码
* @param rawPassword
* @param encodedPassword
* @return
*/
public boolean matches(CharSequence rawPassword, String encodedPassword) {
String rawPass = MD5Util.encode((String) rawPassword);
boolean result = rawPass.equals(encodedPassword);
return result;
}
});
}
配置动态设置资源权限
代码语言:javascript复制 protected void configure(HttpSecurity http) throws Exception {
List<PermissionEntity> allPermission = permissionMapper.findAllPermission();
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry
expressionInterceptUrlRegistry = http.authorizeRequests();
allPermission.forEach((permission) -> {
/**
* 动态添加资源的访问权限
*/
expressionInterceptUrlRegistry.antMatchers(permission.getUrl()).
hasAnyAuthority(permission.getPermTag());
});
expressionInterceptUrlRegistry.antMatchers("/login").permitAll()
.antMatchers("/**").fullyAuthenticated()
.and().formLogin().loginPage("/login").and().csrf().disable();
}