java Spring Oauth2 隐式流

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33831057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 22:10:44  来源:igfitidea点击:

Spring Oauth2 implicit flow

javaspringspring-mvcoauthspring-security

提问by Fabian Lurz

Working on implementing Oauth2 with Spring. I want to implement the implicit workflow:

致力于使用 Spring 实现 Oauth2。我想实现隐式工作流程:

My configuration file:

我的配置文件:

@Configuration
@EnableAutoConfiguration
@RestController
public class App {

    @Autowired
    private DataSource dataSource;

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    @RequestMapping("/")
    public String home() {
        return "Hello World";
    }

    @Configuration
    @EnableResourceServer
    protected static class ResourceServer extends ResourceServerConfigurerAdapter {

        @Autowired
        private TokenStore tokenStore;

        @Override
        public void configure(ResourceServerSecurityConfigurer resources)
                throws Exception {
            resources.tokenStore(tokenStore);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            // @formatter:off
        http.authorizeRequests().antMatchers("/oauth/token").authenticated()
                .and()
                .authorizeRequests().anyRequest().permitAll()
                .and()
                .formLogin().loginPage("/login").permitAll()
                .and()
                .csrf().disable();
        }

    }

    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private AuthenticationManager auth;

        private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

        @Bean
        public JdbcTokenStore tokenStore() {
            return new JdbcTokenStore(DBConnector.dataSource);
        }

        @Bean
        protected AuthorizationCodeServices authorizationCodeServices() {
            return new JdbcAuthorizationCodeServices(DBConnector.dataSource);
        }

        @Override
        public void configure(AuthorizationServerSecurityConfigurer security)
                throws Exception {
            security.passwordEncoder(passwordEncoder);
        }

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints)
                throws Exception {
            endpoints.authorizationCodeServices(authorizationCodeServices())
                    .authenticationManager(auth).tokenStore(tokenStore())
                    .approvalStoreDisabled();            
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            // @formatter:off
            clients.jdbc(DBConnector.dataSource)
                    .passwordEncoder(passwordEncoder)
                    .withClient("my-trusted-client")
                    .secret("test")
                    .authorizedGrantTypes("password", "authorization_code",
                            "refresh_token", "implicit")
                    .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                    .scopes("read", "write", "trust")
                    .resourceIds("oauth2-resource")
                    .accessTokenValiditySeconds(0);

            // @formatter:on
        }

    }

    @Autowired
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        // @formatter:off 
        auth.jdbcAuthentication().dataSource(DBConnector.dataSource).withUser("dave")
                .password("secret").roles("USER");

        // @formatter:on
    }

}

This is working so far. A user is also generated in the database.

到目前为止,这是有效的。还会在数据库中生成一个用户。

Problem is following. When i try to do following request:

问题如下。当我尝试执行以下请求时:

http://localhost:8080/oauth/token?grant_type=authorization_code&client_id=my-trusted-client&username=dave&password=secret

http://localhost:8080/oauth/token?grant_type=authorization_code&client_id=my-trusted-client&username=dave&password=secret

I always get a popup window (authentication) asking me to enter a username and a password. But it doesn't matter what i enter there i never pass through. So what is wrong there?

我总是收到一个弹出窗口(身份验证),要求我输入用户名和密码。但不管我进入那里,我永远不会通过。那么有什么问题呢?

I would like to have it, that when i call this url, that i get back my access_token.

我想要它,当我调用这个 url 时,我会取回我的 access_token。

采纳答案by Imrank

In case of implicit flow all token will be generated through authorization url instead of token url. so you should hit ../oauth/authorize endpoint with implicit response type. i.e

在隐式流的情况下,所有令牌都将通过授权 url 而不是令牌 url 生成。所以你应该使用隐式响应类型点击 ../oauth/authorize 端点。IE

../oauth/authorize?response_type=implicit&client_id=trusted_client&redirect_uri=<redirect-uri-of-client-application>.

You are getting the username password popup because token endpoint is already protected through spring's BasicAuthenticationFilter and it is expecting you to pass your client_id as username and client_secret as password. Instead of token endpoint you need to protect authorization endpoint so do your endpoint security configuration as given...

您正在收到用户名密码弹出窗口,因为令牌端点已经通过 spring 的 BasicAuthenticationFilter 受到保护,并且希望您将 client_id 作为用户名传递,将 client_secret 作为密码传递。您需要保护授权端点而不是令牌端点,因此请按照给定的方式执行端点安全配置...

 @Override
        public void configure(HttpSecurity http) throws Exception {
            // @formatter:off
        http.authorizeRequests().antMatchers("/oauth/authorize").authenticated()
                .and()
                .authorizeRequests().anyRequest().permitAll()
                .and()
                .formLogin().loginPage("/login").permitAll()
                .and()
                .csrf().disable();
        }