提交 c593d624 编写于 作者: alvachien's avatar alvachien

Retry new way

上级 b9107f54
package com.poc.alvachien.authserverdemo.config;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.UUID;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
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.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
@Configuration(proxyBeanMethods = false)
public class AuthorizationServerConfig {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
http
.exceptionHandling(exceptions ->
exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
// @Bean
// public OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
// return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository);
// }
// @Bean
// public OAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
// return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository);
// }
@Bean
public JWKSource<SecurityContext> jwkSource() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAKey rsaKey = new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
JWKSet jwkSet = new JWKSet(rsaKey);
return new ImmutableJWKSet<>(jwkSet);
}
private static KeyPair generateRsaKey() {
KeyPair keyPair;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
return keyPair;
}
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
@Bean
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder()
.build();
}
}
......@@ -25,6 +25,7 @@ import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
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.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
......@@ -47,8 +48,10 @@ import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration
@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
public class SecurityConfig {
private final MyUserDetailsService userDetailService;
......@@ -58,151 +61,132 @@ public class SecurityConfig {
this.userDetailService = userDetailsService;
}
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
//http.sessionManagement().
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
// http
// .authorizeRequests(authorizeRequests ->
// authorizeRequests
// .mvcMatchers("/assets/**", "/webjars/**", "/login").permitAll()
// .anyRequest().authenticated()
// )
http
// .csrf().disable()
// Redirect to the login page when not authenticated from the authorization endpoint
.exceptionHandling((exceptions) -> exceptions
.authenticationEntryPoint(
new LoginUrlAuthenticationEntryPoint("/login"))
)
// Accept access tokens for User Info and/or Client Registration
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
// @Bean
// @Order(1)
// public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
// OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
// //http.sessionManagement().
// http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
// .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
// // http
// // .authorizeRequests(authorizeRequests ->
// // authorizeRequests
// // .mvcMatchers("/assets/**", "/webjars/**", "/login").permitAll()
// // .anyRequest().authenticated()
// // )
// http
// // .csrf().disable()
// // Redirect to the login page when not authenticated from the authorization endpoint
// .exceptionHandling((exceptions) -> exceptions
// .authenticationEntryPoint(
// new LoginUrlAuthenticationEntryPoint("/login"))
// )
// // Accept access tokens for User Info and/or Client Registration
// .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
// return http.build();
// }
// @Bean
// @Order(2)
// public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
// http
// .authorizeHttpRequests((authorize) -> authorize
// .requestMatchers("/", "/static/**", "/register**", "/home", "/about").permitAll()
// .anyRequest().authenticated()
// )
// // Form login handles the redirect to the login page from the
// // authorization server filter chain
// .formLogin(
// form -> form
// .loginPage("/login")
// //.loginProcessingUrl("/login")
// .defaultSuccessUrl("/user")
// .permitAll()
// )
// .logout(
// logout -> logout
// .logoutUrl("/logout")
// .logoutSuccessUrl("/")
// .permitAll()
// )
// .rememberMe()
// .rememberMeServices(getRememberMeServices())
// .key(SECRET_KEY)
// ;
// return http.build();
// }
// private TokenBasedRememberMeServices getRememberMeServices() {
// TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(SECRET_KEY, userDetailService);
// services.setCookieName("remember-cookie");
// services.setTokenValiditySeconds(100);
// return services;
// }
// @Bean
// OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer() {
// return context -> {
// if (OidcParameterNames.ID_TOKEN.equals(context.getTokenType().getValue())) {
// UserDetails detail = userDetailService.loadUserByUsername(context.getPrincipal().getName());
// OidcUserInfo userInfo = OidcUserInfo.builder()
// .subject(detail.getUsername())
// .name(detail.getUsername())
// .givenName("First")
// .familyName("Last")
// .middleName("Middle")
// .nickname("User")
// .preferredUsername(detail.getUsername())
// .profile("https://example.com/" + detail.getUsername())
// .picture("https://example.com/" + detail.getUsername() + ".jpg")
// .website("https://example.com")
// .email(detail.getUsername() + "@example.com")
// .emailVerified(true)
// .gender("female")
// .birthdate("1970-01-01")
// .zoneinfo("Europe/Paris")
// .locale("en-US")
// .phoneNumber("+1 (604) 555-1234;ext=5678")
// .phoneNumberVerified(false)
// // .claim("address", Collections.singletonMap("formatted", "Champ de Mars\n5 Av. Anatole France\n75007 Paris\nFrance"))
// .updatedAt("1970-01-01T00:00:00Z")
// .build();
// context.getClaims().claims(claims ->
// claims.putAll(userInfo.getClaims()));
// }
// if (context.getTokenType() == OAuth2TokenType.ACCESS_TOKEN) {
// Authentication principal = context.getPrincipal();
// Set<String> authorities = principal.getAuthorities().stream()
// .map(GrantedAuthority::getAuthority)
// .collect(Collectors.toSet());
// context.getClaims().claim("roles", authorities);
// }
// };
// }
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/", "/static/**", "/register**", "/home", "/about").permitAll()
.anyRequest().authenticated()
)
// Form login handles the redirect to the login page from the
// authorization server filter chain
// .authorizeHttpRequests(authorize ->
// authorize.anyRequest().authenticated()
// )
//.formLogin(withDefaults());
.formLogin(
form -> form
.loginPage("/login")
//.loginProcessingUrl("/login")
.defaultSuccessUrl("/user")
.permitAll()
)
.logout(
logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.permitAll()
form -> form.loginPage("/login").loginProcessingUrl("/login").successForwardUrl("/")
)
.rememberMe()
.rememberMeServices(getRememberMeServices())
.key(SECRET_KEY)
;
.authorizeHttpRequests(
requests -> requests.requestMatchers("/", "/home", "/login", "/static/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
private TokenBasedRememberMeServices getRememberMeServices() {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(SECRET_KEY, userDetailService);
services.setCookieName("remember-cookie");
services.setTokenValiditySeconds(100);
return services;
}
@Bean
OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer() {
return context -> {
if (OidcParameterNames.ID_TOKEN.equals(context.getTokenType().getValue())) {
UserDetails detail = userDetailService.loadUserByUsername(context.getPrincipal().getName());
OidcUserInfo userInfo = OidcUserInfo.builder()
.subject(detail.getUsername())
.name(detail.getUsername())
.givenName("First")
.familyName("Last")
.middleName("Middle")
.nickname("User")
.preferredUsername(detail.getUsername())
.profile("https://example.com/" + detail.getUsername())
.picture("https://example.com/" + detail.getUsername() + ".jpg")
.website("https://example.com")
.email(detail.getUsername() + "@example.com")
.emailVerified(true)
.gender("female")
.birthdate("1970-01-01")
.zoneinfo("Europe/Paris")
.locale("en-US")
.phoneNumber("+1 (604) 555-1234;ext=5678")
.phoneNumberVerified(false)
// .claim("address", Collections.singletonMap("formatted", "Champ de Mars\n5 Av. Anatole France\n75007 Paris\nFrance"))
.updatedAt("1970-01-01T00:00:00Z")
.build();
context.getClaims().claims(claims ->
claims.putAll(userInfo.getClaims()));
}
if (context.getTokenType() == OAuth2TokenType.ACCESS_TOKEN) {
Authentication principal = context.getPrincipal();
Set<String> authorities = principal.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toSet());
context.getClaims().claim("roles", authorities);
}
};
}
@Bean
public JWKSource<SecurityContext> jwkSource() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAKey rsaKey = new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
JWKSet jwkSet = new JWKSet(rsaKey);
return new ImmutableJWKSet<>(jwkSet);
}
private static KeyPair generateRsaKey() {
KeyPair keyPair;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
return keyPair;
}
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
@Bean
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder()
.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
String idForEncode = "bcrypt";
......
......@@ -42,12 +42,18 @@ public class MainController {
@GetMapping("/login")
public String loginForm(Model model) {
log.info("Requiring /login");
LoginDto ld = new LoginDto();
model.addAttribute("login", ld);
return "login";
}
// @GetMapping("/login")
// public String loginForm(Model model) {
// log.info("Requiring /login");
// LoginDto ld = new LoginDto();
// model.addAttribute("login", ld);
// return "login";
// }
// @PostMapping("/login")
// public String login(@Valid @ModelAttribute("login") LoginDto loginData,
// BindingResult result, Model model) {
......
......@@ -17,7 +17,23 @@
</div>
<main class="form-signin w-100 m-auto">
<form method="post" role="form" th:action="@{/login}" th:object="${login}">
<form method="post" th:action="@{/login}">
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
<div class="form-group mb-3">
<label for="username" class="sr-only">Email</label>
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required="" autofocus="" spellcheck="false" data-ms-editor="true">
</div>
<div class="form-group mb-3">
<label for="password" class="sr-only">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required="">
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
</form>
<!-- <form method="post" role="form" th:action="@{/login}" th:object="${login}">
<img class="mb-4" th:src="@{/static/img/logo.svg}" alt="" width="72" height="57">
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
......@@ -42,7 +58,7 @@
<input type="checkbox" value="remember-me"> Remember me </label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
</form>
</form> -->
</main>
<div th:replace="~{fragments/footer :: footer}">&copy; 2022 - 2023</div>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册