使用Spring Security将密码授予更改为隐式授权

时间:2016-03-18 08:45:24

标签: java spring spring-security spring-security-oauth2

我使用带有OAuth2的“密码”授权类型的AngularJS客户端有一个有效的Spring Boot 1.3.1应用程序。我知道这不是很好,因为每个人都可以在AngularJS代码中看到client_id和client_secret。

我想改为“隐含”补助金。我的授权服务器和资源服务器在同一个应用程序中运行。

这是我当前的授权服务器配置:

@Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private MyApplicationSecuritySettings securitySettings;

        @Autowired
        private AuthenticationManager authenticationManager;

        @Autowired
        private UserDetailsService userDetailsService;

        @Autowired
        private PasswordEncoder passwordEncoder;

        @Autowired
        private DataSource dataSource;

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()                       
                   .withClient(securitySettings.getAngularClientId())
                   .authorizedGrantTypes("password","refresh_token")
                   .scopes("read", "write")
                   .resourceIds(RESOURCE_ID)
                   .secret(passwordEncoder.encode(securitySettings.getAngularClientSecret()));

        }

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

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

        @Bean
        @Primary
        public DefaultTokenServices tokenServices() {
            DefaultTokenServices tokenServices = new DefaultTokenServices();
            tokenServices.setSupportRefreshToken(true);
            tokenServices.setTokenStore(tokenStore());
            return tokenServices;
        }

        @Bean
        public TokenStore tokenStore() {
            return new JdbcTokenStore(dataSource) {

                // Workaround for https://github.com/spring-projects/spring-boot/issues/5071

                @Override
                protected OAuth2Authentication deserializeAuthentication(byte[] authentication) {
                    ObjectInputStream input = null;
                    try {
                        input = new ConfigurableObjectInputStream(
                                new ByteArrayInputStream(authentication),
                                Thread.currentThread().getContextClassLoader());
                        return (OAuth2Authentication) input.readObject();
                    } catch (Exception ex) {
                        throw new IllegalArgumentException(ex);
                    } finally {
                        if (input != null) {
                            try {
                                input.close();
                            } catch (IOException ex) {
                                // Continue
                            }
                        }
                    }
                }
            };
        }
    }

我也有这个WebSecurityConfigurerAdapter子类:

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // Disable security for bower components
        web.ignoring().antMatchers("/components/**");
    }

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

这是资源服务器的配置:

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(RESOURCE_ID);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http
                .authorizeRequests()
                .antMatchers("/admin", "/admin/", "/index.html", "/home.html", "/", "/logout",
                             "/partials/login.html"
                )
                .permitAll()                   
                .authorizeRequests()
                .antMatchers("/management/**").hasRole("ADMIN")
                .anyRequest().authenticated();
    }
}

使用此配置,可以通过/oauth/token请求令牌。当用户访问http://localhost:8080/admin/#/login并在该HTML表单中键入其用户名和密码时,会在AngularJS中实现此功能。

对于隐式授权,我将ClientDetailsServiceConfigurer更改为:

@Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()                       
                   .withClient(securitySettings.getAngularClientId())
                   .authorizedGrantTypes("implicit")
                   .scopes("read", "write")
                   .resourceIds(RESOURCE_ID);                       
        }

如果我尝试以下网址:http://localhost:8080/oauth/authorize?client_id=angularClient&response_type=token

浏览器重定向到http://localhost:8080/login并显示:

<oauth>
<error_description>Full authentication is required to access this resource</error_description>
<error>unauthorized</error>
</oauth>

我是否错误地测试了这个隐式流程?

我是否需要更改配置中的某些内容,以便重定向转到http://localhost:8080/admin/#/login?或者,角度应用是否需要从http://localhost:8080/admin/#/login转到http://localhost:8080/oauth/authorize,在某处传递用户的用户名和密码?

0 个答案:

没有答案