我正在尝试使用OAuth2以及简单的Spring Security(Web安全适配器)来实现身份验证系统。但是当我尝试配置时,我无法同时使用这两种服务。根据下面分享的配置文件代码,但它可以使用弹簧安全性(Web安全适配器)使用OAuth2或简单身份验证。我希望身份验证系统都能基于URL识别工作。
提前致谢!
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
public class ConfigurationClass {
// Its working as simple auth spring security
@EnableWebSecurity
@Configuration
@Order(1)
protected static class StatelessAuthenticationSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private TokenAuthenticationService tokenAuthenticationService;
@Autowired
private OtpManage OtpManage;
@Autowired
private RoleRepository RoleRepository;
public StatelessAuthenticationSecurityConfig() {
super(true);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// allow anonymous resource requests
.antMatchers("/").permitAll()
// allow anonymous POSTs to login
.antMatchers(HttpMethod.POST, "/user/registration").permitAll()
.antMatchers(HttpMethod.POST, "/user/changepassword").permitAll()
.antMatchers(HttpMethod.POST, "/user/resetpassword").permitAll()
// .antMatchers(HttpMethod.POST,
// "/api/otpResetPassword").permitAll()
.antMatchers(HttpMethod.POST, "/user/saveusergroup").permitAll()
.antMatchers(HttpMethod.POST, "/user/bugreport").permitAll()
.antMatchers(HttpMethod.POST, "/user/createtoken").permitAll()
// .anyRequest().authenticated().and()
.anyRequest().hasAnyRole("USER","SYSTEM_ADMIN","ADMIN").and()
// custom JSON based authentication by POST of
// {"username":"<name>","password":"<password>"} which sets the
// token header upon authentication
.addFilterBefore(new StatelessLoginFilter("/api/login", tokenAuthenticationService, userDetailsService,
authenticationManager(), OtpManage), UsernamePasswordAuthenticationFilter.class)
// custom Token based authentication based on the header
// previously given to the client
.addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService),
UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected UserDetailsService userDetailsService() {
return userDetailsService;
}
}
// Its not working, But if I removed @Order(1) annotation from StatelessAuthenticationSecurityConfig class then this one will work as default
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
@Autowired
private CustomLogoutSuccessHandler customLogoutSuccessHandler;
@Override
public void configure(HttpSecurity http) throws Exception {
System.out.println("@EnableResourceServer");
http
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
.and()
.logout()
.logoutUrl("/oauth/logout")
.logoutSuccessHandler(customLogoutSuccessHandler)
.and()
.csrf()
.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize"))
.disable()
.headers()
.frameOptions().disable().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/hello/").permitAll()
.antMatchers("/secure/**").authenticated();
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter implements EnvironmentAware {
private static final String ENV_OAUTH = "authentication.oauth.";
private static final String PROP_CLIENTID = "clientid";
private static final String PROP_SECRET = "secret";
private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds";
private RelaxedPropertyResolver propertyResolver;
@Autowired
private DataSource dataSource;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints
.tokenStore(tokenStore())
.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
System.out.println("@AuthorizationServerConfigurerAdapter");
clients
.inMemory()
.withClient(propertyResolver.getProperty(PROP_CLIENTID))
.scopes("read", "write")
.authorities(Authorities.ROLE_ADMIN.name(), Authorities.ROLE_USER.name())
.authorizedGrantTypes("password", "refresh_token")
.secret(propertyResolver.getProperty(PROP_SECRET))
.accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800));
}
@Override
public void setEnvironment(Environment environment) {
this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_OAUTH);
}
}
}
更新
我使用 @ EnableOAuth2Client,@ Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)对我的代码进行了一些更改,我已经实现了我想要做的事情。但现在问题是我无法使用用户凭据调用发布网址:“/ api / login”。我收到错误 url not found 。根据我在WebSecurityConfig类中的代码,我在loginFilter类的configure(HttpSecurity http)方法中添加了filter,它扩展了AbstractAuthenticationProcessingFilter。但是这个用“/ api / login”url映射的过滤器根本不起作用。为什么这个过滤器不起作用我不明白。有人可以帮助我。
#WebSecurityConfigClass
/**
* Implementation of HttpSecurity configure method
* Implementation custom JSON based authentication by POST of {"username":"<name>","password":"<password>"} which sets the token header upon authentication
* @author Santosh
*
*/
@EnableOAuth2Client
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true, securedEnabled = true, proxyTargetClass = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private TokenAuthenticationService tokenAuthenticationService;
@Autowired
private MessageSource messages;
@Autowired
private RESTAuthenticationEntryPoint authenticationEntryPoint;
@Autowired
private RESTAuthenticationSuccessHandler restAuthenticationSuccessHandler;
@Autowired
private RESTAuthenticationFailureHandler restAuthenticationFailureHandler;
@Autowired
private CustomAccessDeniedHandler accessDeniedHandler;
public WebSecurityConfig() {
super(true);
}
/*@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
auth.inMemoryAuthentication().withUser("testUser").password("testUser").roles("USER");
}
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// setup security
http
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.anyRequest()
.fullyAuthenticated()
.and().httpBasic();
http
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.anonymous().and()
.servletApi().and()
.headers().and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/login").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.and()
.authorizeRequests()
.anyRequest().hasAnyRole("USER").and()
//all other request need to be authenticated
// custom JSON based authentication by POST of {"username":"<name>","password":"<password>"} which sets the token header upon authentication
.addFilterBefore(new LoginFilter("/api/login", tokenAuthenticationService, userDetailsService, authenticationManager(), restAuthenticationSuccessHandler, restAuthenticationFailureHandler), UsernamePasswordAuthenticationFilter.class)
// custom Token based authentication based on the header previously given to the client
.addFilterBefore(new ApplicationFilter (tokenAuthenticationService, messages), UsernamePasswordAuthenticationFilter.class);
}
// To allow Pre-flight [OPTIONS] request from browser
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
web.ignoring()//allow anonymous GETs to API
.antMatchers(HttpMethod.GET, "/api/status/**");
}
@Bean
public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Bean
public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint(){
return new CustomBasicAuthenticationEntryPoint();
}
@Bean(name="authenticationManagerBean")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
#OAuth2ServerConfiguration
@Configuration
public class OAuth2ServerConfiguration {
private static final String RESOURCE_ID = "restservice";
private static final String ROLE_ADMIN = "ADMIN";
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private CustomOAuth2AccessDeniedHandler accessDeniedHandler;
@Autowired
private RESTOAuth2AuthenticationEntryPoint restAuthenticationEntryPoint;
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/hello").permitAll()
.antMatchers("/users/current/**","/oauth/token","/oauth/authorize","/oauth/refresh_token").permitAll()
.antMatchers("/api/greeting").authenticated().and().exceptionHandling()
.accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(restAuthenticationEntryPoint);
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private DataSource dataSource;
@Autowired
private TokenStore tokenStore;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
// @Autowired
// private UserApprovalHandler userApprovalHandler;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(this.tokenStore).authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService);
// .userApprovalHandler(userApprovalHandler)
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// jdbc(dataSource)
clients.inMemory().withClient("clientapp").authorizedGrantTypes("password", "refresh_token")
.authorities("USER").scopes("read", "write").resourceIds(RESOURCE_ID).secret("123456")
.accessTokenValiditySeconds(20)// Access token is only valid
// for 2 minutes.
.refreshTokenValiditySeconds(1200);// Refresh token is only
// valid for 10
// minutes.;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
}
}
}
答案 0 :(得分:0)
在您的WebSecurityAdapter
上构建requestMatchers以确定HttpSecurity实例将调用哪些请求。
例如:
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/secure/path", "/more/secure/path");
// Rest of your configuration.
}