Spring Security(Spring安全框架)学习笔记(一)简介、自定义登录页面、放过静态资源
Spring Security(Spring安全框架)学习笔记(二)登录接口,登录参数,登录回调,注销登录
Spring Security(Spring安全框架)学习笔记(三)返回json格式数据,适用前后端分离场景
Spring Security(Spring安全框架)学习笔记(四)授权操作、权限继承
Spring Security(Spring安全框架)学习笔记(五)整合Mysql数据库
授权操作
1. SecurityConfig.java
package com.hx.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import java.io.PrintWriter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
// 密码加密实例
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance(); // 采用不加密方式
}
/**
* 在内存中创建用户的方法
* 与之前的创建方法不同
* spring Security支持多种方式去创建用户
* @return
*/
@Override
@Bean
protected UserDetailsService userDetailsService(){
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("whx").password("a").roles("admin").build());
manager.createUser(User.withUsername("hx").password("a").roles("user").build());
return manager;
}
/**
* 权限继承
* @return
*/
@Bean
RoleHierarchy roleHierarchy(){
RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_admin > ROLE_user"); //设置权限继承,管理员权限>用户权限
return hierarchy;
}
/**
* 放过资源
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**", "/css/**", "images/**"); //放过静态资源下的js,css,img资源
}
/**
* http安全配置
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//authorizeRequests开启配置
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin") //从上往下依次匹配
.antMatchers("/user/**").hasRole("user")
.anyRequest() //拦截规则:anyRequest所有请求都拦截,必须写在前边两个的后边
.authenticated()
.and()
.formLogin() //formLogin表单配置
.loginProcessingUrl("/doLogin") //指定登录请求接口,若不配置则与指定的loginPage相同
//登录成功的回调
.successHandler((req,resp,authentication) -> { //authentication:存储用户信息
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//将用户信息以json格式返回给前端
out.write(new ObjectMapper().writeValueAsString(authentication.getPrincipal()));
out.flush();
out.close();
})
//登录失败的回调
.failureHandler((req,resp,exception) -> {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//将错误信息以json格式返回给前端
out.write(new ObjectMapper().writeValueAsString(exception.getMessage()));
out.flush();
out.close();
})
.permitAll()
.and()
.logout()
.logoutUrl("/logout") //配置退出登录地址
.logoutSuccessHandler((req,resp,authentication) -> {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//将错误信息以json格式返回给前端
out.write(new ObjectMapper().writeValueAsString("loginout success"));
out.flush();
out.close();
})
.and()
.csrf().disable() //关闭csrf
.exceptionHandling()
.authenticationEntryPoint((req,resp,e) -> {
resp.setContentType("application/json;charset=utf-8");
resp.setStatus(401); //设置响应状态码,401
PrintWriter out = resp.getWriter();
//将错误信息以json格式返回给前端
out.write(new ObjectMapper().writeValueAsString("unlogin"));
out.flush();
out.close();
});
}
}