第二次
This commit is contained in:
@@ -1,2 +1,51 @@
|
||||
server:
|
||||
port: 9000
|
||||
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: sp4-oauth2-authorization-server
|
||||
# 数据源配置(用于存储客户端和授权信息)
|
||||
datasource:
|
||||
url: jdbc:h2:mem:oauth2db
|
||||
driver-class-name: org.h2.Driver
|
||||
username: sa
|
||||
password:
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: create-drop
|
||||
show-sql: true
|
||||
# OAuth2授权服务器配置
|
||||
security:
|
||||
# 默认用户(用于授权服务器管理)
|
||||
user:
|
||||
name: admin
|
||||
password: admin123
|
||||
roles: ADMIN
|
||||
oauth2:
|
||||
authorizationserver:
|
||||
# 客户端注册配置
|
||||
issuer: http://localhost:9000
|
||||
client:
|
||||
login-client:
|
||||
registration:
|
||||
client-id: "login-client"
|
||||
client-secret: "{noop}openid-connect"
|
||||
client-authentication-methods:
|
||||
- "client_secret_basic"
|
||||
authorization-grant-types:
|
||||
- "authorization_code"
|
||||
- "refresh_token"
|
||||
redirect-uris:
|
||||
- "http://127.0.0.1:8080/login/oauth2/code/login-client"
|
||||
- "http://127.0.0.1:8080/authorized"
|
||||
scopes:
|
||||
- "openid"
|
||||
- "profile"
|
||||
- "email"
|
||||
- "address"
|
||||
require-authorization-consent: true
|
||||
|
||||
logging:
|
||||
level:
|
||||
org.springframework.security: trace
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.bamanker.sp4oauth2client.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfig {
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeHttpRequests(authorize -> authorize
|
||||
.requestMatchers("/admin/**").hasRole("ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.formLogin(Customizer.withDefaults()
|
||||
)
|
||||
.csrf(Customizer.withDefaults())
|
||||
.httpBasic(Customizer.withDefaults()
|
||||
);
|
||||
return http.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.bamanker.sp4oauth2client.controller;
|
||||
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 测试控制器
|
||||
*/
|
||||
@RestController
|
||||
public class HomeController {
|
||||
/**
|
||||
* 首页
|
||||
* 需要认证才能访问
|
||||
*/
|
||||
@GetMapping("/")
|
||||
public Map<String, Object> home(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient client,
|
||||
@AuthenticationPrincipal OAuth2User oauth2User) {
|
||||
return Map.of(
|
||||
"message", "欢迎使用OAuth2登录",
|
||||
"user", oauth2User.getName(),
|
||||
"client", client.getClientRegistration().getClientName(),
|
||||
"userAttributes", oauth2User.getAttributes()
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 获取当前用户信息
|
||||
*/
|
||||
@GetMapping("/user")
|
||||
public OAuth2User user(@AuthenticationPrincipal OAuth2User oauth2User) {
|
||||
return oauth2User;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.bamanker.sp4oauth2client.filter;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
//@Component
|
||||
//@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class LoopbackIpRedirectFilter extends OncePerRequestFilter {
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, @Nonnull HttpServletResponse response
|
||||
, @Nonnull FilterChain filterChain) throws ServletException, IOException {
|
||||
if (request.getServerName().equals("localhost") && request.getHeader("host") != null) {
|
||||
UriComponents uri = UriComponentsBuilder.fromUriString(request.getRequestURL().toString())
|
||||
.host("127.0.0.1")
|
||||
.build();
|
||||
response.sendRedirect(uri.toUriString());
|
||||
return;
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.bamanker.sp4oauth2client.service;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
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.Service;
|
||||
|
||||
@Service
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(@NonNull String username) throws UsernameNotFoundException {
|
||||
if ("admin".equals(username)) {
|
||||
return User.withUsername("admin")
|
||||
.password("{noop}password")
|
||||
.roles("ADMIN")
|
||||
.build();
|
||||
}
|
||||
throw new UsernameNotFoundException("User not found");
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,61 @@
|
||||
server:
|
||||
port: 8081
|
||||
port: 8080
|
||||
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: sp4-oauth2-demo
|
||||
# OAuth2客户端配置
|
||||
security:
|
||||
oauth2:
|
||||
client:
|
||||
registration:
|
||||
login-client:
|
||||
provider: spring
|
||||
client-id: login-client
|
||||
client-secret: openid-connect
|
||||
client-authentication-method: client_secret_basic
|
||||
authorization-grant-type: authorization_code
|
||||
redirect-uri: http://127.0.0.1:8080/login/oauth2/code/login-client
|
||||
scope: openid,profile,email,address
|
||||
client-name: Spring
|
||||
provider:
|
||||
spring:
|
||||
authorization-uri: http://localhost:9000/oauth2/authorize
|
||||
token-uri: http://localhost:9000/oauth2/token
|
||||
jwk-set-uri: http://localhost:9000/oauth2/jwks
|
||||
|
||||
# Google登录配置
|
||||
# google:
|
||||
# client-id: your-google-client-id # 从Google Cloud Console获取
|
||||
# client-secret: your-google-client-secret # 从Google Cloud Console获取
|
||||
# scope: # 请求的权限范围
|
||||
# - openid
|
||||
# - profile
|
||||
# - email
|
||||
# redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}" # 回调地址
|
||||
# authorization-grant-type: authorization_code # 授权码模式
|
||||
# client-name: Google # 客户端显示名称
|
||||
# # GitHub登录配置
|
||||
# github:
|
||||
# client-id: your-github-client-id # 从GitHub Settings > Developer settings > OAuth Apps获取
|
||||
# client-secret: your-github-client-secret
|
||||
# scope:
|
||||
# - read:user
|
||||
# - user:email
|
||||
# redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
|
||||
# authorization-grant-type: authorization_code
|
||||
# client-name: GitHub
|
||||
# 提供者配置(如果使用标准OIDC提供者,可以自动发现)
|
||||
# google:
|
||||
# issuer-uri: https://accounts.google.com # OIDC Issuer URI,会自动发现配置
|
||||
# github:
|
||||
# authorization-uri: https://github.com/login/oauth/authorize # 授权端点
|
||||
# token-uri: https://github.com/login/oauth/access_token # 令牌端点
|
||||
# user-info-uri: https://api.github.com/user # 用户信息端点
|
||||
# user-name-attribute: login # 用户名属性名
|
||||
logging:
|
||||
level:
|
||||
root: info
|
||||
org.springframework.web: info
|
||||
org.springframework.security: trace
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.bamanker.sp4oauth2resourceserver.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfig {
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeHttpRequests(authorize -> authorize
|
||||
.requestMatchers("/admin/**").hasRole("ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.formLogin(Customizer.withDefaults()
|
||||
)
|
||||
.csrf(Customizer.withDefaults())
|
||||
.httpBasic(Customizer.withDefaults()
|
||||
);
|
||||
return http.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.bamanker.sp4oauth2resourceserver.controller;
|
||||
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* API控制器
|
||||
* 演示OAuth2资源服务器保护API
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class ApiController {
|
||||
/**
|
||||
* 用户API
|
||||
* 需要有效的OAuth2访问令牌
|
||||
*/
|
||||
@GetMapping("/user/info")
|
||||
public Map<String, Object> userInfo() {
|
||||
return Map.of(
|
||||
"message", "这是受保护的API"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员API
|
||||
* 需要admin权限
|
||||
*/
|
||||
@GetMapping("/admin/data")
|
||||
public Map<String, Object> adminData() {
|
||||
return Map.of(
|
||||
"message", "这是管理员API"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.bamanker.sp4oauth2resourceserver.service;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
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.Service;
|
||||
|
||||
@Service
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(@NonNull String username) throws UsernameNotFoundException {
|
||||
if ("admin".equals(username)) {
|
||||
return User.withUsername("admin")
|
||||
.password("{noop}password")
|
||||
.roles("ADMIN")
|
||||
.build();
|
||||
}
|
||||
throw new UsernameNotFoundException("User not found");
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,9 @@
|
||||
server:
|
||||
port: 8080
|
||||
port: 8081
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: sp4-oauth2-resource-server
|
||||
logging:
|
||||
level:
|
||||
org.springframework.security: trace
|
||||
|
||||
Reference in New Issue
Block a user