Spring Security password fails verification - spring

I was following Spring Security articles:
[Spring Security without WebSecurityConfigurerAdapter]: https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
[Spring Security Blog]: http://staging5.baeldung.com/spring-deprecated-websecurityconfigureradapter
and I keep getting the error:
o.s.s.a.dao.DaoAuthenticationProvider : Failed to authenticate since password does not match stored value
Below is my SecurityConfig class:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true,
jsr250Enabled=true)
public class WebSecurityConfig {
private static final String ROLE_ADMIN_USER = "ADMIN_USER";
private static final String ROLE_POWER_USER = "POWER_USER";
private static final String ROLE_GUEST_USER = "GUEST_USER";
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
UserDetails user1 = User.withUsername("user1")
.password(passwordEncoder().encode("user1abc"))
.roles(ROLE_ADMIN_USER).build();
UserDetails user2 = User.withUsername("user2")
.password(passwordEncoder().encode("user2abc"))
.roles(ROLE_POWER_USER).build();
UserDetails user3 = User.withUsername("user3")
.password(passwordEncoder().encode("user3abc"))
.roles(ROLE_GUEST_USER).build();
return new InMemoryUserDetailsManager(user1, user2, user3);
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/index").hasAnyRole(ROLE_ADMIN_USER, ROLE_POWER_USER, ROLE_GUEST_USER)
.antMatchers("/inventory").hasAnyRole(ROLE_ADMIN_USER, ROLE_POWER_USER)
.antMatchers("/guest").hasAnyRole(ROLE_GUEST_USER)
.antMatchers("/login*").permitAll()
.antMatchers("/doLogin").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("j_username")
.passwordParameter("j_password")
.loginProcessingUrl("/doLogin")
.defaultSuccessUrl("/index", true)
.successHandler(new AuthenticationSuccessHandler() {
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
System.out.println("--- Login successful ---");
}
})
.failureUrl("/login");
return http.build();
}

Related

Spring Security multiple UserDetailsService

I have 3 different tables and every table has user-information. (Maybe the same username but different passwords)
Also, have 3 different URLs for authorization. Is it possible to use multiple UserDetailsService with one configuration and during authorization control which table to use?
Here is my configuration code but I can't control which table to use during authorization:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
#Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final AuthenticationManagerBuilder authenticationManagerBuilder;
#Qualifier("userDetailsService")
private final UserDetailsService userDetailsService;
#Qualifier("customerDetailsService")
private final UserDetailsService customerDetailsService;
private final TokenProvider tokenProvider;
private final CorsFilter corsFilter;
private final SecurityProblemSupport problemSupport;
public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService, UserDetailsService customerDetailsService, TokenProvider tokenProvider, CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
this.authenticationManagerBuilder = authenticationManagerBuilder;
this.userDetailsService = userDetailsService;
this.customerDetailsService = customerDetailsService;
this.tokenProvider = tokenProvider;
this.corsFilter = corsFilter;
this.problemSupport = problemSupport;
}
#PostConstruct
public void init() {
try {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder())
.and()
.userDetailsService(customerDetailsService)
.passwordEncoder(passwordEncoder());
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.csrf()
.disable()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/account/reset-password/init").permitAll()
.antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/info").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/v2/api-docs/**").permitAll()
.antMatchers("/swagger-resources/configuration/ui").permitAll()
.antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN)
.and()
.apply(securityConfigurerAdapter());
}
private JWTConfigurer securityConfigurerAdapter() {
return new JWTConfigurer(tokenProvider);
}
}
userDetailsService and customerDetailsService are my UserDetailsService implementations that use different tables for check credential. But I can't control exactly which UserDetailsService to use when a request came.
You can use this article
https://sanketdaru.com/blog/multiple-sources-user-details-spring-security/ .
It has example in which it defines two services in service and use that single service. Just like my code of user detail service.
#Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
List<UserEntity> users = userRepository.findByName(name);
if (users.isEmpty()){
return inMemoryUserDetailsService.loadUserByUsername(name);
}
return new UserDetailEntity (users.get(0));
}
#PostConstruct
public void init() {
this.inMemoryUserDetailsService = initInMemoryUserDetailsService();
}
private UserDetailsService initInMemoryUserDetailsService() {
List<UserDetails> userDetails = new ArrayList<>();
UserDetails userDetails1 = new User("user1", "$2a$10$t/U97dFDQ0e8ujCq6728P.E1axs/aoAMsopoSUQtTchiKTP/Ps4um", Collections.singletonList(new SimpleGrantedAuthority("USER")));
UserDetails userDetails2 = new User("admin1", "$2a$10$t/U97dFDQ0e8ujCq6728P.E1axs/aoAMsopoSUQtTchiKTP/Ps4um", Arrays.asList(new SimpleGrantedAuthority("USER"),new SimpleGrantedAuthority("ADMIN")));
userDetails.add(userDetails1);
userDetails.add(userDetails2);
return new InMemoryUserDetailsManager(userDetails);
}
Please try it in WebSecurityConfigurerAdapter
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(yourCustomUserDetailsService).passwordEncoder(passwordEncoder);
}

Spring security: My Authorization filter authorizes my request even tho the URL is permited

In my security configuration class i have permitted the request to the welcome url and any other url which follows the "welcome/**" format.
this is my securityconfiguration class:
#EnableGlobalMethodSecurity(prePostEnabled = true)
//#Configuration
#EnableWebSecurity
public class JwtSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
private final CustomerDetailsService customerDetailsService;
#Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
#Autowired
public JwtSecurityConfiguration(CustomerDetailsService customerDetailsService) {
this.customerDetailsService = customerDetailsService;
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(customerDetailsService)
.passwordEncoder(passwordEncoderBean());
}
#Bean
public PasswordEncoder passwordEncoderBean() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("**/resources/static/**")
.and()
.ignoring()
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/index_assets/**"
);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/welcome/login").permitAll()
.antMatchers("/welcome").permitAll()
.antMatchers("/welcome/signup").permitAll()
.antMatchers("admin/rest/**").authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
//http.addFilterBefore(new JWTAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);
http.addFilterBefore(new JWTAuthorizationFilter(authenticationManager(),customerDetailsService),UsernamePasswordAuthenticationFilter.class);
// disable page caching
http
.headers()
.frameOptions().sameOrigin() // required to set for H2 else H2 Console will be blank.
.cacheControl();
//http.headers().cacheControl();
}
}
but I noticed that in my JWTAuthorizationFilter.class the doFilterInternal() method picks up this URL
public class JWTAuthorizationFilter extends OncePerRequestFilter {
private final CustomerDetailsService customerDetailsService;
#Autowired
DefaultCookieService defaultCookieService;
public JWTAuthorizationFilter(AuthenticationManager authenticationManager, CustomerDetailsService customerDetailsService) {
// super(authenticationManager);
this.customerDetailsService = customerDetailsService;
}
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String header = request.getHeader(HEADER);
if(Objects.isNull(header) || !header.startsWith(TOKEN_PREFIX)){
return;
}
UsernamePasswordAuthenticationToken usernamePasswordAuth = getAuthenticationToken(request);
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuth);
chain.doFilter(request,response);
}
private UsernamePasswordAuthenticationToken getAuthenticationToken(HttpServletRequest request){
String token = request.getHeader(HEADER);
if(Objects.isNull(token)) return null;
String username = Jwts.parser().setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX,""))
.getBody()
.getSubject();
UserDetails userDetails = customerDetailsService.loadUserByUsername(username);
return username != null ? new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()) : null;
}
}
What is the cause of this ?
Filter is suppose to pick up each and every request. It doesn't matter if that you have permitted or not in security configuration.
You have got two options:
If you don't want welcome/** to go through the filter you add it to web ignore
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("**/resources/static/**")
.and()
.ignoring()
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/index_assets/**",
"/welcome/**"
);
}
But note, it will skip all filters and you may not want that.
In doFilterInternal method skip it when you find welcome/** pattern.

PermitAll not working in Spring Security

I have two rules, the first one every url from oauth/** should be without security and and other url have to security. But now all urls are secure include url from oauth/**.
This is my security config rule.
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
// JWT dont need CSRF
httpSecurity.csrf().disable().exceptionHandling().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
.antMatchers("oauth/**").permitAll().and()
.addFilterBefore(new JwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class);
// disable page caching
httpSecurity.headers().cacheControl();
}
}
when I request the url http://localhost:8080/oauth/fb that is enter my JwtAuthenticationTokenFilter, and I want this url don't enter this filter.
You can override configure method with WebSecurity parameter.
#Override
public void configure(final WebSecurity web) throws Exception
{
web.ignoring().antMatchers("oauth/**");
}
This method should be used when serving static content such as css/* js/*, suggested in the documentation, however I couldn't find another way to permit URL mapping with custom filter in Spring Security.
<security:http pattern="/support/**" security="none"/>
You would probably need to write the Java equivalent of the above XML configuration. Basically, you are setting a new filter chain with no security for the above pattern.
I faced a similar problem. My security config:
// ... imports
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
private final PasswordEncoder passwordEncoder;
private final JwtFilter jwtFilter;
#Autowired
public SecurityConfig(#Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder,
JwtProvider jwtProvider) {
this.userDetailsService = userDetailsService;
this.passwordEncoder = passwordEncoder;
this.jwtFilter = new JwtFilter(jwtProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/auth/**").permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
protected DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
provider.setPasswordEncoder(passwordEncoder);
return provider;
}
}
And my security filter:
// ... imports
public class JwtFilter extends GenericFilterBean {
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String TOKEN_PREFIX = "Bearer ";
public static final int TOKEN_START_POSITION = 7;
private final JwtProvider jwtProvider;
#Autowired
public JwtFilter(JwtProvider jwtProvider) {
this.jwtProvider = jwtProvider;
}
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
String token = getTokenFromRequest((HttpServletRequest) servletRequest);
if (token != null && jwtProvider.validateToken(token)) {
Map<String, Object> properties = jwtProvider.getUserPropertiesFromToken(token);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
properties.get("login"),
null,
(Set<GrantedAuthority>) properties.get("authirities"));
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(servletRequest, servletResponse);
}
private String getTokenFromRequest(HttpServletRequest request) {
String bearer = request.getHeader(AUTHORIZATION_HEADER);
if (bearer != null && bearer.startsWith(TOKEN_PREFIX)) {
return bearer.substring(TOKEN_START_POSITION);
}
return null;
}
}
The reason my code didn't work for me was that I skipped the line filterChain.doFilter(servletRequest, servletResponse); in my filter, i.e. I didn't pass on the request and response to the next entity in the chain.

Spring security OAuth2 authentication and form login in one app

Is it possible to combine authoryzation and authentication by login basic and by oauth2 in one application?
My project is based on jhipster project with simple spring security session login, now i need add oauth2 security for mobile app and it's look like it is not possible.
Now i have situation when work one of them, oauth2 ok if WebSecurityConfigurerAdapter had bigger order number than ResourceServerConfiguration. That's mean if oauth security filter is first.
I read a lot in stackoverflow and try many solution like:
Spring security oauth2 and form login configuration for me thats one don't work.
Now i know that is related with some security filter conflict but i dont know how to fix it.
if someone had a similar problem and he managed to do it, or know how to get around or make it better I will be grateful for the information. Thanks in advance for your help :)
#Configuration
#EnableWebSecurity
public class SecurityOauth2Configuration extends WebSecurityConfigurerAdapter {
#Inject
private UserDetailsService userDetailsService;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/scripts/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/assets/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/api/register")
.antMatchers("/api/activate")
.antMatchers("/api/account/reset_password/init")
.antMatchers("/api/account/reset_password/finish")
.antMatchers("/test/**");
}
#Configuration
#EnableAuthorizationServer
public static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private static final String OAUTH_SECURITY = "jhipster.security.authentication.oauth.";
private static final String CLIENTID = "clientid";
private static final String SECRET = "secret";
private static final String TOKEN_VALIDATION_TIME = "tokenValidityInSeconds";
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('"+AuthoritiesConstants.USER+"')").checkTokenAccess("hasAuthority('"+AuthoritiesConstants.USER+"')");
}
#Inject
private Environment env;
#Inject
private DataSource dataSource;
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(tokenStore())
;
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient(env.getProperty(OAUTH_SECURITY + CLIENTID))
.scopes("read", "write")
.authorities(AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER)
.authorizedGrantTypes("password", "refresh_token")
.secret(env.getProperty(OAUTH_SECURITY + SECRET))
.accessTokenValiditySeconds(env.getProperty(OAUTH_SECURITY + TOKEN_VALIDATION_TIME, Integer.class, 18000));
}
}
#Configuration
#Order(1)
public static class SecurityWebConfiguration extends WebSecurityConfigurerAdapter {
#Inject
private Environment env;
#Inject
private AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler;
#Inject
private AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler;
#Inject
private AjaxLogoutOauthSuccessHandler ajaxLogoutSuccessHandler;
#Inject
private RememberMeServices rememberMeServices;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable().authorizeRequests()
.and()
.formLogin()
.loginProcessingUrl("/api/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
.and()
.rememberMe()
.rememberMeServices(rememberMeServices)
.key(env.getProperty("jhipster.security.rememberme.key"))
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.exceptionHandling()
;
}
}
#Order(2)
#Configuration
#EnableResourceServer
public static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Inject
private Http401UnauthorizedEntryPoint authenticationEntryPoint;
#Inject
private AjaxLogoutOauthSuccessHandler ajaxLogoutSuccessHandler;
#Override
public void configure(HttpSecurity http) throws Exception {
ContentNegotiationStrategy contentNegotiationStrategy = http.getSharedObject(ContentNegotiationStrategy.class);
if (contentNegotiationStrategy == null) {
contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
}
MediaTypeRequestMatcher preferredMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,
MediaType.APPLICATION_FORM_URLENCODED,
MediaType.APPLICATION_JSON,
MediaType.MULTIPART_FORM_DATA);
http
.authorizeRequests()
.and()
.anonymous()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic()
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.defaultAuthenticationEntryPointFor(authenticationEntryPoint, preferredMatcher)
.and()
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated();
}
}
}
For this settings WebSecurityConfigurerAdapter session work correctly. For OAuth after correctly authorizatization i get valid acces token, but for request with this token from session i get this result:
public static String getCurrentLogin() {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
UserDetails springSecurityUser = null;
String userName = null;
if(authentication != null) {
if (authentication.getPrincipal() instanceof UserDetails) {
springSecurityUser = (UserDetails) authentication.getPrincipal();
userName = springSecurityUser.getUsername();
} else if (authentication.getPrincipal() instanceof String) {
userName = (String) authentication.getPrincipal();
}
}
System.out.println(userName); // show anonymousUser
System.out.println(authentication.isAuthenticated()); //show true
System.out.println(authentication.getAuthorities()); //show [ROLE_ANONYMOUS]
System.out.println(userName); //show anonymousUser
return userName;
}
function write in console:
anonymousUser
true
[ROLE_ANONYMOUS]
anonymousUser
and should be user1
true
[ROLE_USER]
user1
The apps git urls:
https://github.com/rynkowsw/oauth2 it is oauth2 app
https://github.com/rynkowsw/web-and-oauth2-security this is web and oauth2 security app
This app are adapted from jhipster.github.io
to run app you need have postgres db in localhost, like in db resource file:
driver-class-name: org.postgresql.ds.PGSimpleDataSource
url: jdbc:postgresql://localhost:5432/gymapp
name: gymapp
serverName: localhost:5432
username: postgres
password: jaja
To test app the fastest way is:
http://localhost:8080/oauth/token
headers: Authorization: Basic amhpcHN0ZXJhcHA6bXlTZWNyZXRPQXV0aFNlY3JldA==
this string after basic is combination default jhispter oauth secret and clientid base64 encrypt result
then
http://localhost:8080/api/account
headers: Authorization: bearer [token from response in first request]
For this same db, result for oauth are:
for oauth2 app
{
login: "user"
password: null
firstName: "User"
lastName: "User"
email: "user#localhost"
activated: true
langKey: "en"
authorities: [1]
0: "ROLE_USER"
-
}
for web + oauth2 security:
{
login: "anonymousUser"
password: null
firstName: "Anonymous"
lastName: "User"
email: "anonymous#localhost"
activated: true
langKey: "en"
authorities: [0]
}

Spring injection of userdetailsservice in security config class fails

I am new to spring security and i am trying to configure it using java but when i try to inject a UserDetailsService into a security config class i get a 404 error page but when i inject it into a controller the injection works. am using spring version 4.1.6 and spring security 4.0.0
here is my security config class
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("loginService")
UserDetailsService loginService; //THIS IS THE POINT OF FAILURE
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/userlist")
.failureUrl("/")
.permitAll()
.and()
.logout()
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
/*auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");*/
auth.userDetailsService(loginService).passwordEncoder(passwordEncoder());
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**");
}
#Bean
public Md5PasswordEncoder passwordEncoder(){
Md5PasswordEncoder encoder = new Md5PasswordEncoder();
return encoder;
}
}
This is the UserDetailsService class
#Service("loginService")
public class LoginService implements UserDetailsService{
#Autowired
UserRepository userRepository;
#Transactional
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SiteUser user = userRepository.findByUsername(username);
Collection<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
SimpleGrantedAuthority userAuthority = new SimpleGrantedAuthority("ROLE_USER");
SimpleGrantedAuthority adminAuthority = new SimpleGrantedAuthority("ROLE_ADMIN");
User u = null;
if(user == null)
throw new UsernameNotFoundException("No such User: " + username);
else
{
if (user.getRole().equals("USER"))
authorities.add(userAuthority);
else if (user.getRole().equals("ADMIN"))
{
authorities.add(userAuthority);
authorities.add(adminAuthority);
}
u = new User(user.getUsername(), user.getPassword(), authorities);
}
return u;
}
}
The rest of the project is available
here
The solution was to add
#ComponentScan("com.ashken.*")
on top of the securityconfig class
I've found that it is less troublesome to simply register your implementation of UserDetailsService as a bean in SecurityConfig:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserRepository userRepository;
#Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
#Transactional
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SiteUser user = userRepository.findByUsername(username);
Collection<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
SimpleGrantedAuthority userAuthority = new SimpleGrantedAuthority("ROLE_USER");
SimpleGrantedAuthority adminAuthority = new SimpleGrantedAuthority("ROLE_ADMIN");
User u = null;
if(user == null) {
throw new UsernameNotFoundException("No such User: " + username);
} else {
if (user.getRole().equals("USER")) {
authorities.add(userAuthority);
} else if (user.getRole().equals("ADMIN")) {
authorities.add(userAuthority);
authorities.add(adminAuthority);
}
u = new User(user.getUsername(), user.getPassword(), authorities);
}
return u;
}
};
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/userlist")
.failureUrl("/")
.permitAll()
.and()
.logout()
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
/*auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");*/
auth.userDetailsService(loginService).passwordEncoder(passwordEncoder());
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**");
}
#Bean
public Md5PasswordEncoder passwordEncoder(){
Md5PasswordEncoder encoder = new Md5PasswordEncoder();
return encoder;
}
}

Resources