我使用带有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,在某处传递用户的用户名和密码?