Spring Cloud Security OAuth2 中实现简化模式(二)

2023-04-13 19:42:11 浏览数 (1)

编写授权页面

在 Spring Security 中,可以使用 AuthorizationRequest 对象和 OAuth2AuthorizationRequest 对象来保存授权请求信息。授权页面可以使用 Thymeleaf 模板引擎来渲染,例如:

代码语言:javascript复制
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Login</title>
</head>
<body>
    <form th:action="@{/oauth/authorize}" method="post">
        <input type="hidden" name="response_type" value="token"/>
        <input type="hidden" name="client_id" th:value="${authorizationRequest.clientId}"/>
        <input type="hidden" name="redirect_uri" th:value="${authorizationRequest.redirectUri}"/>
        <input type="hidden" name="scope" th:value="${authorizationRequest.scope}"/>
        <h2>Authorize</h2>
        <p>Client name: <span th:text="${authorizationRequest.clientId}"></span></p>
        <p>Scope: <span th:text="${authorizationRequest.scope}"></span></p>
        <button type="submit">Approve</button>
        <button type="button" onclick="window.location='/';">Deny</button>
    </form>
</body>
</html>

在上面的授权页面中,使用隐藏域来保存 response_typeclient_idredirect_uriscope 参数,这些参数用在上面的授权页面中,使用隐藏域来保存 response_typeclient_idredirect_uriscope 参数,这些参数用于向认证服务器发起授权请求。同时,使用 Thymeleaf 模板引擎来渲染授权页面,使其更加美观和易于维护。

配置安全拦截器

最后一步是配置安全拦截器,用于保护资源服务器和认证服务器的安全。这里我们可以使用 Spring Security 提供的 @EnableWebSecurity 注解来配置安全拦截器。

代码语言:javascript复制
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login**", "/error**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password("{noop}password").roles("USER");
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}

在上面的代码中,使用 @EnableWebSecurity 注解开启 Web 安全性。使用 configure(HttpSecurity http) 方法来配置 HTTP 请求的安全拦截器,其中 antMatchers() 方法用于配置 URL 的匹配规则,authenticated() 方法用于指定需要进行身份认证。使用 configure(AuthenticationManagerBuilder auth) 方法来配置用户的身份认证信息,这里使用内存存储方式。最后,使用 authenticationManagerBean() 方法来创建 AuthenticationManager 对象,并交给 Spring 容器管理。

测试授权流程

在完成上述配置后,我们可以使用浏览器来测试授权流程。首先,访问授权客户端的首页,点击“Login”按钮,跳转到认证服务器的登录页面,输入用户名和密码进行登录。登录成功后,跳转到授权页面,点击“Approve”按钮,认证服务器将颁发令牌,将令牌返回给授权客户端的 JavaScript 脚本。脚本将令牌保存到浏览器的 sessionStorage 中,用于后续的资源访问。。

代码语言:javascript复制
<!DOCTYPE html>
<html>
<head>
    <title>OAuth2 Simplified Mode Demo</title>
    <meta charset="UTF-8">
    <script>
        function login() {
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/oauth/token', true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.onload = function() {
                if (xhr.status === 200) {
                    var response = JSON.parse(xhr.responseText);
                    sessionStorage.setItem('access_token', response.access_token);
                    sessionStorage.setItem('token_type', response.token_type);
                    sessionStorage.setItem('expires_in', response.expires_in);
                    window.location.href = '/secure';
                } else {
                    alert('Something went wrong...');
                }
            };
            xhr.send('grant_type=implicit&client_id=client&scope=read&redirect_uri=http://localhost:8081/redirect');
        }
    </script>
</head>
<body>
    <h1>Welcome to OAuth2 Simplified Mode Demo</h1>
    <button onclick="login()">Login</button>
</body>
</html>

在上面的代码中,使用 JavaScript 实现了一个简单的授权客户端,点击“Login”按钮,将向认证服务器发起授权请求,并将返回的访问令牌保存到浏览器的 sessionStorage 中。最后,页面跳转到受保护的资源服务器,使用保存的访问令牌来访问资源。

代码语言:javascript复制
@RestController
public class ResourceController {

    @GetMapping("/secure")
    public String helloWorld(Principal principal) {
        return "Hello, "   principal.getName();
    }

}

在上面的代码中,使用 Spring MVC 实现了一个简单的资源服务器,其中 @GetMapping("/secure") 注解用于指定 URL 的匹配规则,Principal 参数用于获取当前用户的信息。在本例中,使用 principal.getName() 方法获取当前用户的用户名,并返回相应的字符串。

0 人点赞