/*
* Copyright (c) 2020 mental4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.aiplus.mental.auth.config;
import com.aiplus.mental.auth.support.core.FormIdentityLoginConfigurer;
import com.aiplus.mental.auth.support.core.MentalDaoAuthenticationProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.annotation.web.configurers.RequestCacheConfigurer;
import org.springframework.security.web.SecurityFilterChain;
/**
* 服务安全相关配置
*
* @author lengleng
* @date 2022/1/12
*/
@EnableWebSecurity
public class WebSecurityConfiguration {
/**
* spring security 默认的安全策略
* @param http security注入点
* @return SecurityFilterChain
* @throws Exception
*/
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorizeRequests ->
authorizeRequests
.requestMatchers("/token/*")
.permitAll()// 开放自定义的部分端点
.anyRequest()
.authenticated()
);
http.headers(header ->
header
.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)// 避免iframe同源无法登录许iframe
);
http.with(new FormIdentityLoginConfigurer(), Customizer.withDefaults()); // 表单登录个性化
http.sessionManagement(sessionManagement -> sessionManagement
.maximumSessions(1) // 限制同一个用户只能有一个会话
.maxSessionsPreventsLogin(true) // 如果设置为true,当达到最大会话数时,拒绝新的登录
);
// 处理 UsernamePasswordAuthenticationToken
http.authenticationProvider(new MentalDaoAuthenticationProvider());
return http.build();
}
/**
* 暴露静态资源
*
* https://github.com/spring-projects/spring-security/issues/10938
* @param http
* @return
* @throws Exception
*/
@Bean
@Order(0)
SecurityFilterChain resources(HttpSecurity http) throws Exception {
http.securityMatchers((matchers) -> matchers.requestMatchers("/actuator/**", "/css/**", "/error"))
.authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll())
.requestCache(RequestCacheConfigurer::disable)
.securityContext(AbstractHttpConfigurer::disable)
.sessionManagement(AbstractHttpConfigurer::disable);
return http.build();
}
}