I'm attempting to use a custom authentication manager but the standard Provider manager is being called to .authenticate. I suspect it has something to do with either the AuthSever or Web Config. Any help is greatly appreciated.
AuthServer configuration:
#Configuration
#EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private final DataSource dataSource;
#Autowired
public AuthServerConfig(DataSource dataSource){
this.dataSource = dataSource;
}
#Autowired
MicrosJwtConfig microsJwtConfig;
#Autowired
#Qualifier("microsProviderManager")
AuthenticationManager authenticationManager;
public BCryptPasswordEncoder encoder(){
return new BCryptPasswordEncoder(10);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.tokenServices(microsJwtConfig.microsTokenServices())
.authenticationManager(authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.allowFormAuthenticationForClients();
security.passwordEncoder(encoder());
security.tokenKeyAccess("permitAll()");
}
}
WebSecurity config:
#EnableWebSecurity
#Configuration
public class WebSecConfig extends WebSecurityConfigurerAdapter {
#Autowired
private ClientDetailsService clientDetailsService;
#Autowired
private MECAuthenticationProvider mecAuthenticationProvider;
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return new MicrosProviderManager(clientDetailsService, mecAuthenticationProvider );
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("actuator/health").permitAll().and()
.authorizeRequests().antMatchers("oauth/token").permitAll().and()
.authorizeRequests().antMatchers("actuator/info").permitAll();
}
}
Related
I'm getting internal server error while running my code. i have no idea what happened because It shows nothing in console.
here my AuthorizationServerConfig class
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private DataSource dataSource;
#Autowired
private AuthenticationManager authenticationManager;
#Bean
TokenStore jdbcTokenStore() {
return new JdbcTokenStore(dataSource);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()").tokenKeyAccess("permitAll()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(jdbcTokenStore());
endpoints.authenticationManager(authenticationManager);
}
}
here my websecurityconfig code
#EnableWebSecurity
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Bean
protected AuthenticationManager getAuthenticationManager() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public static PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
this is my userserviceImpl
#Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserDetailRepository userDetailRepository;
#Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
Optional<User> optionalUser = userDetailRepository.findByUsername(name);
optionalUser.orElseThrow(() -> new UsernameNotFoundException("Username or password wrong"));
UserDetails userDetails = new AuthUserDetail(optionalUser.get());
new AccountStatusUserDetailsChecker().check(userDetails);
return userDetails;
}
}
this is how i get token
http://localhost:8802/oauth/token?grant_type=password&username=abc&scope=READ&password=abc *
output
{
"error": "server_error",
"error_description": "Internal Server Error"
}
spring boot oauth2 ResourceServerConfigurerAdapter not protecting resourcs
/oauth/token working fine.
.antMatchers("/api/waiter/**") in resourceserver is accessible by public.
.antMatchers("/api/waiter/").hasAnyRole(RESTRWAITER).antMatchers("/api/waiter/").authenticated()
i have clearly defined role for api.
seem like problem in resource server configuration.
My Codes Are
#Configuration
#EnableResourceServer
#Order(2)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Value("${spring.datasource.driver-class-name}")
private String oauthClass;
#Value("${spring.datasource.url}")
private String oauthUrl;
#Value("${spring.datasource.username}")
private String username;
#Value("${spring.datasource.password}")
private String password;
private static final String RESTRWAITER = "WAITER";
#Bean
public TokenStore tokenStore() {
DataSource tokenDataSource = DataSourceBuilder.create().driverClassName(oauthClass).username(username)
.password(password).url(oauthUrl).build();
return new JdbcTokenStore(tokenDataSource);
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("scout").tokenStore(tokenStore());
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.anonymous().disable().requestMatchers().antMatchers("/api/waiter/**").and().authorizeRequests()
.antMatchers("/api/waiter/**").hasAnyRole(RESTRWAITER).antMatchers("/api/waiter/**").authenticated().and().exceptionHandling()
.accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
And
AuthorizationServerConfig
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Value("${spring.datasource.driver-class-name}")
private String oauthClass;
#Value("${spring.datasource.url}")
private String oauthUrl;
#Value("${spring.datasource.username}")
private String username;
#Value("${spring.datasource.password}")
private String password;
#Bean
public TokenStore tokenStore() {
System.out.println(username);
DataSource tokenDataSource = DataSourceBuilder.create().driverClassName(oauthClass).username(username)
.password(password).url(oauthUrl).build();
return new JdbcTokenStore(tokenDataSource);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.authenticationManager(authenticationManager);
endpoints.tokenStore(tokenStore());
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients();
}
#Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("clientapp").secret(getPasswordEncoder().encode("123456"))
.authorizedGrantTypes("password", "authorization_code", "refresh_token").authorities("READ_ONLY_CLIENT")
.scopes("read_profile_info").resourceIds("oauth2-resource").redirectUris("http://localhost:8081/login")
.accessTokenValiditySeconds(120000).refreshTokenValiditySeconds(240000);
}
}
and
SecurityConfiguration
#Configuration
#EnableWebSecurity
#Order(1)
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
#EnableAspectJAutoProxy(proxyTargetClass = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final String SYSTEM = "SYSTEM";
private static final String RESTRUSER = "RESTRO";
private static final String RESTRWAITER = "WAITER";
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private DataSource dataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());
}
#Bean
public AuthenticationFailureHandler customAuthenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/api/waiter/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**").hasRole(SYSTEM).antMatchers("/restro/**")
.hasAnyRole(RESTRUSER).antMatchers("/waiter/**").hasAnyRole(RESTRWAITER).antMatchers("/", "/pub/**")
.permitAll().and().formLogin().loginPage("/login").defaultSuccessUrl("/dashboard")
.failureHandler(customAuthenticationFailureHandler()).permitAll().and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/?logout")
.deleteCookies("my-remember-me-cookie").permitAll().and().rememberMe()
// .key("my-secure-key")
.rememberMeCookieName("my-remember-me-cookie").tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(24 * 60 * 60).and().exceptionHandling();
}
PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepositoryImpl = new JdbcTokenRepositoryImpl();
tokenRepositoryImpl.setDataSource(dataSource);
return tokenRepositoryImpl;
}
#Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
The problem is resource server .antMatchers("/api/waiter/**") is accessible without access_token.
Resource server configuration not working.
Got found solution
just replaced #Order(1) with #Order(SecurityProperties.BASIC_AUTH_ORDER) on SecurityConfiguration . And its worked.
#Configuration
#EnableWebSecurity
#Order(SecurityProperties.BASIC_AUTH_ORDER)
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
#EnableAspectJAutoProxy(proxyTargetClass = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
I am getting access denied on accessing request based on role. I don't know why. I am using spring security with oauth2 in spring boot.
The configured authorization server is -
#EnableAuthorizationServer
#Configuration
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authManager;
#Autowired
private AuthConfig config;
#Autowired
private UserDetailsService userDetailsService;
#Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient(config.getClientId()).secret("{noop}".concat(config.getClientSecret()))
.scopes("read", "write").authorizedGrantTypes("password", "refresh_token")
.accessTokenValiditySeconds(config.getAccessTokenValidity())
.refreshTokenValiditySeconds(config.getRefresTokenValidity());
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.pathMapping("/oauth/token", config.getAuthPath());
endpoints.authenticationManager(authManager).tokenStore(tokenStore()).accessTokenConverter(jwtTokenEnhancer());
endpoints.userDetailsService(userDetailsService);
}
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtTokenEnhancer());
}
#Bean
protected JwtAccessTokenConverter jwtTokenEnhancer() {
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"),
config.getKeyStorePassword().toCharArray());
JwtAccessTokenConverter converter = new CustomTokenEnhancer();
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt"));
return converter;
}
}
and resource server is configured as
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my_rest_api";
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/create/user").permitAll().antMatchers("/hello").hasRole("superadmin")
.anyRequest().authenticated().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER);
}
}
and sever security configured as
#Configuration
#EnableWebSecurity(debug = true)
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
and decoded data in generated token is
{
"exp": 1547123578,
"user_name": "superadmin",
"authorities": [
{
"authority": "ROLE_superadmin"
}
],
"jti": "e1f6e67c-16b8-4a12-a300-fae7f406359e",
"client_id": "pgcil",
"scope": [
"read",
"write"
]
}
but http request http://localhost:8089/hello with jwt token gives acccess denied error. May anyone tell me what i am doing wrong.Any help would be appreciated.
We are using this class for our oauth2 requirements and we can successfully add users and clients when we start the program but we would like to know is there any way we can add more clients and users later i.e. while the java program is running through a #request? Please help.
#SpringBootApplication
#EnableResourceServer
#RestController
public class Oauth2TwApplication {
#RequestMapping(value = "/user")
public Principal user(Principal user) {
return user;
}
public static void main(String[] args) {
SpringApplication.run(Oauth2TwApplication.class, args);
}
#Configuration
#EnableAuthorizationServer
protected static class OAuth2AuthorizationConfig extends
AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
DataSource dataSource;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.jdbc(dataSource)
;
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
TokenStore tokenStore = new JdbcTokenStore(dataSource);
endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.checkTokenAccess("permitAll()");
}
}
#Configuration
#Order(-10)
protected static class LoginConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
DataSource dataSource;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().loginPage("/login").permitAll()
.and()
.requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
.and()
.authorizeRequests()
.anyRequest().authenticated();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManager);
JdbcUserDetailsManager userDetailsService = new JdbcUserDetailsManager();
userDetailsService.setDataSource(dataSource);
PasswordEncoder encoder = new BCryptPasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
auth.jdbcAuthentication().dataSource(dataSource);
if (!userDetailsService.userExists("user")) {
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("USER"));
User userDetails = new User("user", encoder.encode("password"), authorities);
userDetailsService.createUser(userDetails);
}
}
}
}
MyViewControllers
#Controller
public class MyViewControllers extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/oauth/confirm_access").setViewName("authorize");
}
}
Browser Response for localhost:9999/uaa/oauth/authorize?response_type=code&client_id=acme&redirect_uri=http://example.com is 302 Found, but response for localhost:9999/uaa/login is 401 Unauthorized.
I could get the login token prior to adding the #EnableResourceServer. I am using Spring boot and extending WebSecurityConfigurerAdapter to use authentication Manager with data source. When I tried to add a ResourceServerConfigurerAdapter it wouldn't build. What is the easiest way to allow the login page?
#SpringBootApplication
#RestController
#EnableResourceServer
public class OAuthSvcApplication extends WebMvcConfigurerAdapter {
private static final Logger log = LoggerFactory.getLogger(OAuthSvcApplication.class);
#RequestMapping("/user")
public Principal user(Principal user) {
return user;
}
public static void main(String[] args) {
SpringApplication.run(OAuthSvcApplication.class, args);
}
}
#Configuration
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureAuth(AuthenticationManagerBuilder auth,DataSource dataSource, Environment env)
throws Exception {
auth.jdbcAuthentication().dataSource(dataSource);
}
#Configuration
#EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private DataSource dataSource;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security)
throws Exception {
security.checkTokenAccess("hasAuthority('USER')");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.inMemory()
.withClient("acme")
.secret("acmesecret")
.authorizedGrantTypes("authorization_code",
"refresh_token", "password").scopes("openid");
}
}
}
SpringSecurityFilterChain should always be ordered before other filters.
If you want to add your own authentication for all or some endpoints the best thing to do is add your own WebSecurityConfigurerAdapter with lower order. Modifying the WebSecurityConfigurerAdapter subclass as follows allows the ResourceServer to work with a jdbc authentication mgr:
#Configuration
#Order(-10)
protected static class LoginConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private DataSource dataSource;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().loginPage("/login").permitAll()
.and()
.requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
.and()
.authorizeRequests().anyRequest().authenticated();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManager).jdbcAuthentication().dataSource(dataSource);
}
}