首页 > 解决方案 > 带有 JWT 的 Spring Security OAuth2 重定向到登录页面

问题描述

我使用 OAuth2 和 JWT 创建了 Spring Security 应用程序。当它运行时,我得到一个登录页面。下面我提到了pom.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>
    <groupId>com.java.oauth</groupId>
    <artifactId>AuthorizationWithOauth2nJWT</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>AuthorizationWithOauth2nJWT</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.0.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
            <version>1.0.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

下面提到了AuthorizationServerConfig.java文件。

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    private String clientId = "client-id";
    private String clientSecret = "my-secret";

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager getauthenticationManager;

    @Bean
    public JwtAccessTokenConverter tokenEnhancer() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("123");
        return converter;
    }

    @Bean
    public JwtTokenStore tokenStore() {
        return new JwtTokenStore(tokenEnhancer());
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(getauthenticationManager).tokenStore(tokenStore())
                .accessTokenConverter(tokenEnhancer());
    }



    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        clients.inMemory()
                .withClient(clientId)
                .secret(clientSecret)
                .scopes("read", "write", "trust")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                .accessTokenValiditySeconds(20000)
                .refreshTokenValiditySeconds(20000);

    }

}

这是 ResourceServerConfig.java 文件。

@Configuration
@EnableResourceServer
@Order(100)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();

        http.requestMatchers().antMatchers("/oauth/**")
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/**").authenticated();

    }
}

这是 SecurityConfig.java 文件。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/oauth/token").permitAll()
                .antMatchers("/getuser").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll()
                .and()
                .csrf().disable();
    }

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

}

下面我提到了application.yml文件

server:
  port: 8081

spring:
  security:
    user:
      name: test
      password: test

security:
  oauth2:
    resource:
      filter-order: 3

我使用邮递员来执行 API。授权和请求正文在下面的图像中定义。

在此处输入图像描述

在此处输入图像描述

执行 API 后,我收到以下响应,状态码为 200。

<html>

<head>
    <title>Login Page</title>
</head>

<body onload='document.f.username.focus();'>
    <h3>Login with Username and Password</h3>
    <form name='f' action='/login' method='POST'>
        <table>
            <tr>
                <td>User:</td>
                <td><input type='text' name='username' value=''></td>
            </tr>
            <tr>
                <td>Password:</td>
                <td><input type='password' name='password'/></td>
            </tr>
            <tr>
                <td colspan='2'><input name="submit" type="submit" value="Login"/></td>
            </tr>
        </table>
    </form>
</body>

</html>

非常感谢解决此问题的任何帮助或解决方法。

标签: javaspringspring-securityoauth-2.0jwt

解决方案


OP 真正想要的是获得一个访问令牌,就好像它是从 API 获得的一样。

为此,OAuth 2.0 定义了两种授权类型

  1. 客户凭证授予
  2. 资源所有者密码凭证授予

在这两种情况下,您都会跳过登录屏幕并调用令牌端点来获取访问令牌。请阅读 RFC(上面的链接)以了解您应该在何时何地采用这些授权类型。

我不是 Spring 专家,因此我在这里链接到在网上找到的教程,该教程解释了 Spring 的两种授权。


推荐阅读