过滤器写完之后,编写配置文件,前后端分离架构的认证配置
import com.alibaba.fastjson.JSON; import com.cupricnitrate.uaa.filter.RestAuthticationFilter; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.config.Customizer; 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.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; /** * `@EnableWebSecurity` 注解 deug参数为true时,开启调试模式,会有更多的debug输出 * * @author 硝酸铜 * @date 2021/6/2 */ @EnableWebSecurity(debug = true) @Slf4j public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http //禁用生成默认的登陆页面 .formLogin(AbstractHttpConfigurer::disable) //关闭httpBasic,采用自定义过滤器 .httpBasic(AbstractHttpConfigurer::disable) //前后端分离架构不需要csrf保护,这里关闭 .csrf(AbstractHttpConfigurer::disable) //禁用生成默认的注销页面 .logout(AbstractHttpConfigurer::disable) .authorizeRequests(req -> req //可公开访问路径 .antMatchers("/authorize/**").permitAll() //访问 /admin路径下的请求 要有ROLE_ADMIN权限 .antMatchers("/admin/**").hasRole("ADMIN") //访问 /api路径下的请求 要有ROLE_USER .antMatchers("/api/**").hasRole("USER") //其他接口只需要认证即可 .anyRequest().authenticated() ) //前后端分离是无状态的,不用session了,直接禁用。 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); //在添加我们自定义的过滤器,替代UsernamePasswordAuthenticationFilter .addFilterAt(restAuthticationFilter(), UsernamePasswordAuthenticationFilter.class); /* .csrf(csrf -> csrf.disable()) //默认的HTTP Basic Auth认证 .httpBasic(Customizer.withDefaults()) //自定义表单登录 .formLogin(form -> form.successHandler((req,res,auth)->{ res.setStatus(HttpStatus.OK.value()); res.setContentType(MediaType.APPLICATION_JSON_VALUE); res.setCharacterEncoding("UTF-8"); res.getWriter().println(JSON.toJSONString(auth)); log.info("认证成功");})) //对 /api 路径下的所有接口进行验证 .authorizeRequests(req -> req.antMatchers("/api/**").hasAnyRole("USER"));*/ } @SneakyThrows private RestAuthticationFilter restAuthticationFilter() { RestAuthticationFilter filter = new RestAuthticationFilter(); //配置AuthenticationManager,是父类的一个方法 filter.setAuthenticationManager(authenticationManager()); //filter的入口 filter.setFilterProcessesUrl("/authorize/login"); return filter; } @Override public void configure(WebSecurity web) throws Exception { // /public 路径下的请求,都不会启动过滤器链 web.ignoring().mvcMatchers("/public/**"); } }我们使用idea 的Http-client功能调用接口试一下
### POST :8080/authorize/login Content-Type: application/json { "username": "user", "password": "12345678" } HTTP/1.1 200 X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-Frame-Options: DENY Set-Cookie: JSESSIONID=9BAAD30C4014FD926C940972E1D13D00; Path=http://www.likecs.com/; HttpOnly Content-Type: application/json;charset=UTF-8 Content-Length: 344 Date: Fri, 04 Jun 2021 10:12:37 GMT Keep-Alive: timeout=60 Connection: keep-alive { "authenticated": true, "authorities": [ { "authority": "ROLE_ADMIN" }, { "authority": "ROLE_USER" } ], "details": { "remoteAddress": "127.0.0.1" }, "name": "user", "principal": { "accountNonExpired": true, "accountNonLocked": true, "authorities": [ { "$ref": "$.authorities[0]" }, { "$ref": "$.authorities[1]" } ], "credentialsNonExpired": true, "enabled": true, "username": "user" } }成功返回,走自定义逻辑,并且返回了json
这才是前后端分离架构的认证逻辑