Hello everyone when I upgrade my application to spring version 2.0.2 I get this exception:
Description: Field connectionFactoryLocator in com.ssp.api.v1.security.SecurityConfiguration required a bean of type 'org.springframework.social.connect.ConnectionFactoryLocator' that could not be found.
here's my code:
SecurityConfiguration.java Configuration
#Configuration
#ComponentScan(basePackages = { "com.ssp.api.vi.security" })
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired private ConnectionFactoryLocator connectionFactoryLocator;
#Autowired private UsersConnectionRepository usersConnectionRepository;
#Autowired private FacebookConnectionSignup facebookConnectionSignup;
#Autowired private SspUserDetailsService sspUserDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/session").permitAll()
.antMatchers("/h2-console/**").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.requestCache()
.requestCache(new NullRequestCache())
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and().csrf().disable();
}
//#Autowired
#Bean
public ProviderSignInController providerSignInController() {
((InMemoryUsersConnectionRepository) usersConnectionRepository)
.setConnectionSignUp(facebookConnectionSignup);
return new ProviderSignInController(
connectionFactoryLocator,
usersConnectionRepository,
new FacebookSignInAdapter());
}
#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider
= new DaoAuthenticationProvider();
authProvider.setUserDetailsService(sspUserDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
#Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder(11);
}
#Override
#Bean(name = BeanIds.AUTHENTICATION_MANAGER)
public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); }
#Override
#Bean(name = BeanIds.USER_DETAILS_SERVICE)
public UserDetailsService userDetailsServiceBean() throws Exception { return this.sspUserDetailsService; }
AuthUtil.java Class
protected static final Logger log = LoggerFactory.getLogger(AuthUtil.class);
public static void authenticate(Connection<?> connection) {
UserProfile userProfile = connection.fetchUserProfile();
String username = userProfile.getUsername();
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, null);
SecurityContextHolder.getContext().setAuthentication(authentication);
log.info("User {} {} connected.", userProfile.getFirstName(), userProfile.getLastName());
}
FacebookConnectionSignup.class Service
#Service
public class FacebookConnectionSignup implements ConnectionSignUp {
#Override
public String execute(Connection<?> connection) {
return connection.getDisplayName();
}
}
FacebookSignInAdapter.java Class
public class FacebookSignInAdapter implements SignInAdapter{
#Override
public String signIn(String userId, Connection<?> connection, NativeWebRequest request) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(
connection.getDisplayName(), null,
Arrays.asList(new SimpleGrantedAuthority("FACEBOOK_USER"))
)
);
return null;
}
}
SocialConfiguration.java Configuration
#Configuration
public class SocialConfiguration {
#Bean
public SignInAdapter authSignInAdapter() {
return (userId, connection, request) -> {
AuthUtil.authenticate(connection);
return null;
};
}
}
### SspUserDetailsService.class Service
#Service
public class SspUserDetailsService implements UserDetailsService {
#Autowired private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findById(username).orElse(null);
if (user == null)
throw new UsernameNotFoundException(username);
return new SspUserDetails(user);
}
}
Console Error:
Description:
Field connectionFactoryLocator in com.ssp.api.v1.security.SecurityConfiguration required a bean of type 'org.springframework.social.connect.ConnectionFactoryLocator' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.social.connect.ConnectionFactoryLocator' in your configuration.
This code works perfectly In Spring 1.5.10 version.
How can I solve this issue?
Before of all thank you!
In Boot 2.x, you need to define the ConnectionFactoryLocator and UsersConnectionRepository in your SecurityConfiguration class, instead of autowiring them:
private ConnectionFactoryLocator connectionFactoryLocator() {
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(new FacebookConnectionFactory(appId, appSecret));
return registry;
}
private UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
return new InMemoryUsersConnectionRepository(connectionFactoryLocator);
}
Here, appId and appSecret are coming from application.properties.
You also need to change the implementation for your ProviderSignInController bean:
#Bean
public ProviderSignInController providerSignInController() {
ConnectionFactoryLocator connectionFactoryLocator = connectionFactoryLocator();
UsersConnectionRepository usersConnectionRepository = getUsersConnectionRepository(connectionFactoryLocator);
((InMemoryUsersConnectionRepository) usersConnectionRepository).setConnectionSignUp(facebookConnectionSignup);
return new ProviderSignInController(connectionFactoryLocator, usersConnectionRepository, new FacebookSignInAdapter());
}
You can find more details here.
Related
I want to apply CustomLoginProcessingFilter in my application but i can't figure out how it works!
I'm using Spring boot 2.7.2, the lastest version when i started studying this.
here's my code
Another custom providers or custom detail services work so well.
But, once i enroll new bean fore login processing filter, AjaxLoginProcessingFilter, they tell me that i need to specify authentitcationManager!
so, i added at filterChain method this in SecurityConfig.java, but it doesn't work.
enter image description here
/**
----------------- SecurityConfig -------------------------
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
#RequiredArgsConstructor
public class SecurityConfig {
private final CustomAuthenticationSuccessHandler authenticationSuccessHandler;
private final CustomAuthenticationFailureHandler authenticationFailureHandler;
private final FormAuthenticationDetailsSource authenticationDetailsSource;
private final AjaxLoginProcessingFilter ajaxLoginProcessingFilter;
#Bean
AuthenticationManager authenticationManager(AuthenticationManagerBuilder builder) throws Exception {
return builder.build();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(registry -> {
registry.antMatchers("/","/users","user/login/**","/login*").permitAll()
.antMatchers("/mypage").hasRole("USER")
.antMatchers("/messages").hasRole("MANAGER")
.antMatchers("/config").hasRole("ADMIN")
.anyRequest().authenticated();
}).formLogin(login -> {
login.loginPage("/login")
.loginProcessingUrl("/login_proc")
.defaultSuccessUrl("/")
.authenticationDetailsSource(authenticationDetailsSource)
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.permitAll();
}).exceptionHandling(exception -> {
exception.accessDeniedHandler(accessDeniedHandler());
})
.addFilterBefore(ajaxLoginProcessingFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
#Bean
public AccessDeniedHandler accessDeniedHandler(){
CustomAccessDeniedHandler accessDeniedHandler = new CustomAccessDeniedHandler();
accessDeniedHandler.setErrorPage("/denied");
return accessDeniedHandler;
}
#Bean
public WebSecurityCustomizer webSecurityCustomizer() throws Exception {
return (web) -> web.ignoring().antMatchers("/resources/**");
}
#Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
/*Explanation:
In the old version you inject AuthenticationManagerBuilder, set userDetailsService, passwordEncoder and build it.
But authenticationManager is already created in this step.
It is created the way we wanted (with userDetailsService and the passwordEncoder).
https://stackoverflow.com/questions/72381114/spring-security-upgrading-the-deprecated-websecurityconfigureradapter-in-spring
*/
#Bean
CustomUserDetailsService customUserDetailsService() {
return new CustomUserDetailsService();
}
#Bean
public AuthenticationProvider authenticationProvider() {
return new CustomAuthenticationProvider();
}
}
-++------------------ AjaxLoginProcessingFilter ---------------------
#Component("loginProcessingFilter")
public class AjaxLoginProcessingFilter extends AbstractAuthenticationProcessingFilter {
private ObjectMapper objectMapper = new ObjectMapper();
public AjaxLoginProcessingFilter() {
super(new AntPathRequestMatcher("/api/login"));
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if(isAjax(request)){
throw new IllegalStateException("Authentication is not supported");
}
AccountDto accountDto = objectMapper.readValue(request.getReader(), AccountDto.class);
if(StringUtils.isEmpty(accountDto.getUsername()) || StringUtils.isEmpty(accountDto.getPassword())){
throw new IllegalArgumentException("Username or password is not empty");
}
AjaxAuthenticationToken authenticationToken = new AjaxAuthenticationToken(accountDto.getUsername(), accountDto.getPassword());
return getAuthenticationManager().authenticate(authenticationToken);
}
private boolean isAjax(HttpServletRequest request) throws IOException {
if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
return true;
}
return false;
}
}
I am trying to implement oauth2 with a jwt in spring boot and the autentication works but when I want to get the refresh_token an error occurs that indicates the following ...
java.lang.IllegalStateException: UserDetailsService is required.
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:464)
at org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper.loadUserDetails(UserDetailsByNameServiceWrapper.java:68)
at org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider.authenticate(PreAuthenticatedAuthenticationProvider.java:103)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175)
at org.springframework.security.oauth2.provider.token.DefaultTokenServices.refreshAccessToken(DefaultTokenServices.java:150)
What am I doing wrong?
These are my files
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Value("${token.secret}")
private String secret;
#Value("${server.servlet.context-path}")
private String contextPath;
#Value("${oauth2.client.id}")
public String CLIENT_ID;
#Value("${oauth2.client.secret}")
public String CLIENT_SECRET;
#Value("${oauth2.scope.read}")
public String SCOPE_READ;
#Value("${oauth2.grant.types}")
public String GRANT_TYPES;
#Value("${oauth2.scopes}")
public String SCOPES;
#Value("${oauth2.access.token.validity}")
public Integer TOKEN_VALID_SECONDS;
#Value("${oauth2.refresh.token.validity}")
public Integer REFRESH_TOKEN_VALID_SECONDS;
#Autowired
private DataSource dataSource;
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(CLIENT_ID)
.secret(passwordEncoder().encode(CLIENT_SECRET))
.authorizedGrantTypes("password", "refresh_token", "client_credentials","authorization_code")
.scopes("read", "write", "trust")
.accessTokenValiditySeconds(TOKEN_VALID_SECONDS)
.refreshTokenValiditySeconds(REFRESH_TOKEN_VALID_SECONDS);
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
#Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer()));
endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancerChain).authenticationManager(authenticationManager);
}
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
#Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
And this is my SecurityConfig class
#EnableGlobalMethodSecurity(securedEnabled=true)
#Configuration
#RequiredArgsConstructor
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private final CustomUserDetailsService customUserDetailsService;
#Autowired
public BCryptPasswordEncoder passwordEncoder;
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/oauth/**").permitAll()
.antMatchers("/oauth/token/**").permitAll()
.antMatchers("/api/**" ).authenticated()
.anyRequest().authenticated()
.and().formLogin().permitAll()
.and().csrf().disable();
}
}
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserService userService;
//login web service url describe on properties file
#Value("${loginServiceUri}")
public String loginServiceUri;
//login web service enabled
#Value("${loginWebServiceEnabled}")
public Boolean loginWebServiceEnabled;
#Override
public UserDetails loadUserByUsername(String username) {
log.debug("Trying to authenticate user with details....");
if (loginWebServiceEnabled && loginServiceUri != null){
//its necessary to call external Web Service to find the user and then look for
//into database
UserDto userDto = this.loginWebService(username);
if (userDto != null) {
// look for the user in data base
log.debug("User found at external login web service trying to look for at data base");
return lookUserDataBase(userDto.getUsername());
} else {
log.error("User not found at external login web service", username);
throw new UsernameNotFoundException(username);
}
} else {
// look for the user in data base
return lookUserDataBase(username);
}
}
/**
* Look for use in data base by user name
* #return
*/
private UserDetails lookUserDataBase(String userName) {
UserEntity user = userService.findEntityByUsername(userName);
if (user == null) {
log.error("User not found in data base", userName);
throw new UsernameNotFoundException(userName);
}
log.debug("User found in data base with userName: " + userName + " and authorities: " + user.getUserAuthority().toString());
return new UserAuthenticatedDetails(user);
}
/**
* Example Login Web Service call login
* #param name
* #return
*/
private UserDto loginWebService (String name){
xxxxxxxxxxx
}
}
Add these in your WebSecurityConfigurerAdapter class
#Autowired
public void setApplicationContext(ApplicationContext context) {
super.setApplicationContext(context);
AuthenticationManagerBuilder globalAuthBuilder = context
.getBean(AuthenticationManagerBuilder.class);
try {
globalAuthBuilder.userDetailsService(userDetailsService);
} catch (Exception e) {
e.printStackTrace();
}
}
There is a "local" AuthenticationManagerBuilder and a "global" AuthenticationManagerBuilder and we need to set it on the global version in order to have this information passed to these other builder contexts.
Read more about it here
I solved with this lines in SecurityConfig;
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer()));
endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancerChain).authenticationManager(authenticationManager);
//this line solved the problem
endpoints.userDetailsService(customUserDetailsService);**
}
Either you configure some inMemory user as follows:
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("password")
.roles("USER")
.and()
.withUser("manager")
.password("password")
.credentialsExpired(true)
.accountExpired(true)
.accountLocked(true)
.authorities("WRITE_PRIVILEGES", "READ_PRIVILEGES")
.roles("MANAGER");
}
or you implement a UserDetailService e.g. which looks up in the database for a user.
I want to dynamically set the jwk-set-uri for different tenant on my resource server which I get the tenant info from a filter. And I have the following resource server config.
#Slf4j
#Import(SecurityProblemSupport.class)
#RequiredArgsConstructor
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private final SecurityProblemSupport problemSupport;
private final RealmProperties realmProperties;
private final MultiTenantManager multiTenantManager;
#Override
public void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(problemSupport).accessDeniedHandler(problemSupport)
.and()
.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
.and().requestMatcher(new OAuthRequestedMatcher()).authorizeRequests().anyRequest()
.fullyAuthenticated();
}
#Bean
public RequestContextListener requestContextListener() {
return new RequestContextListener();
}
private static class OAuthRequestedMatcher implements RequestMatcher {
public boolean matches(HttpServletRequest request) {
String auth = request.getHeader("Authorization");
log.debug("auth decode from request: ", auth);
boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer");
boolean haveAccessToken = request.getParameter("access_token") != null;
return haveOauth2Token || haveAccessToken;
}
}
#Override
public void configure(final ResourceServerSecurityConfigurer config) {
config.resourceId("login-app");
}
#Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.authorizeExchange().anyExchange().authenticated().and().oauth2ResourceServer().jwt()
.jwtDecoder(myCustomDecoder());
return http.build();
}
#Bean
ReactiveJwtDecoder myCustomDecoder() {
return realmProperties.getRealms().stream()
.filter(realm -> realm.getRealm().equals(multiTenantManager.getCurrentTenant()))
.map(realm -> new NimbusReactiveJwtDecoder(((Realm) realm).getJwkSetUri()))
.findFirst()
.orElseThrow(() -> new InternalServerErrorException("cannot find the jwk set url for the realm"));
}
}
But I got an exception saying
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.annotation.ObjectPostProcessor<?>' available
Any help on this? what can I do to dynamic set a jwk set uri to parse the token?
Thanks
-Peng
I solve customizations of token decoding in the following way:
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
// Inject
private String resourceId;
// Inject
private String secret;
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(resourceId);
resources.tokenStore(createTokenStore(new ResourceAccessTokenConverter()));
}
private TokenStore createTokenStore(AccessTokenConverter converter) {
JwtAccessTokenConverter tokenConverter = new CustomJwtAccessTokenConverter();
tokenConverter.setAccessTokenConverter(converter);
tokenConverter.setVerifier(new MacSigner(secret));
TokenStore ts = new JwtTokenStore(tokenConverter);
return ts;
}
public class CustomJwtAccessTokenConverter extends JwtAccessTokenConverter {
#Override
protected Map<String, Object> decode(String token) {
return super.decode(token);
}
#Override
public Map<String, ?> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
return super.convertAccessToken(token, authentication);
}
#Override
public OAuth2AccessToken extractAccessToken(String value, Map<String, ?> map) {
return super.extractAccessToken(value, map);
}
#Override
public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
return super.extractAuthentication(map);
}
}
}
I changed OAUTH2 version from 2.0.3 to 2.0.14 and Authorization Server is not working.
I had this message from server:
o.s.s.o.provider.endpoint.TokenEndpoint : Handling error: InsufficientAuthenticationException, There is no client authentication. Try adding an appropriate authentication filter.
Could you help me and say what is wrong ? I have token storage in database and I want to use ClientDetailsService from memory, but Spring not recognized this.
#Configuration
#EnableAuthorizationServer
public 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;
private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
#Autowired
private AuthenticationManager authenticationManager;
#Bean
protected AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws
Exception {
security.passwordEncoder(passwordEncoder);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.tokenStore(tokenStore())
.authenticationManager(authenticationManager);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws
Exception {
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);
}
}
Security configuration
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsComponent;
#Bean
public PasswordEncoder passwordEncoder() {
return new StandardPasswordEncoder();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws
Exception {
auth
.userDetailsService(userDetailsComponent)
.passwordEncoder(passwordEncoder());
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/register").antMatchers("/console/*")
.antMatchers("/oauth/**");
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Method security configuration.
#EnableGlobalMethodSecurity(prePostEnabled = true,
proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration
{
}
Custom UserDetailsService.
#Component("userDetailsComponent")
public class UserDetailsComponent implements UserDetailsService {
private final Logger log =
LoggerFactory.getLogger(UserDetailsComponent.class);
#Autowired
private UsersRepository usersRepository;
#Override
public UserDetails loadUserByUsername(String login) {
log.debug("Authenticating {}", login);
Users userFromDatabase = null;
if (login.contains("#")) {
userFromDatabase = usersRepository.findByEmail(login);
} else {
userFromDatabase = usersRepository.findByUsername(login);
}
if (userFromDatabase == null) {
throw new UsernameNotFoundException("User " + login + " was not
found in the database");
} else if (!userFromDatabase.getActivated()) {
throw new UserNotActivatedException("User " + login + " is not
activated");
}
Collection<GrantedAuthority> grantedAuthorities = new
ArrayList<GrantedAuthority>();
for (OauthAuthority authority : userFromDatabase.getOauthAuthorities())
{
GrantedAuthority grantedAuthority = new
SimpleGrantedAuthority(authority.getAuthority().getRole());
grantedAuthorities.add(grantedAuthority);
}
return new User(userFromDatabase.getUsername(),
userFromDatabase.getPassword(), grantedAuthorities);
}
}
Properties
authentication.oauth.clientid=game
authentication.oauth.secret=secret
authentication.oauth.tokenValidityInSeconds=2000
I am trying to implement security to my spring boot application and have followed this http://justinrodenbostel.com/2014/05/30/part-5-integrating-spring-security-with-spring-boot-web/ . after implementing this i am getting an error as following :
Expression parsing failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'securityConfiguration': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire method: public void
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setContent
NegotationStrategy(org.springframework.web.accept.ContentNegotiationStrategy);
This is my Application.class
public class Application extends WebMvcConfigurerAdapter{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Value("${spring.datasource.driverClassName}")
private String databaseDriverClassName;
#Value("${spring.datasource.url}")
private String datasourceUrl;
#Value("${spring.datasource.username}")
private String databaseUsername;
#Value("${spring.datasource.password}")
private String databasePassword;
#Bean
public DataSource datasource() {
org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource();
ds.setDriverClassName(databaseDriverClassName);
ds.setUrl(datasourceUrl);
ds.setUsername(databaseUsername);
ds.setPassword(databasePassword);
return ds;
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
#Bean
public LocaleResolver localeResolver()
{
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.US);
return slr;
}
public LocaleChangeInterceptor localeChangeInterceptor()
{
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
// TODO Auto-generated method stub
registry.addInterceptor(localeChangeInterceptor());
}
I have two model classes named Gizmo.java and GizmoChild.java
This is my Controller class
#Controller
public class SampleController {
#RequestMapping("/")
public String index(Model model) {
Gizmo gizmo = new Gizmo();
gizmo.getChildren().add(new GizmoChild());
model.addAttribute("gizmo", gizmo);
return "hello";
}
#RequestMapping("/save")
public String save(Gizmo gizmo) {
System.out.println(gizmo.getField1());
System.out.println(gizmo.getField2());
for(GizmoChild child : gizmo.getChildren()) {
System.out.println(child.getChildField1());
System.out.println(child.getChildField2());
}
return "redirect:/";
}
}
This is my SecurityConfiguration.java
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource datasource;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().authenticated();
http
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/")
.loginPage("/login")
.permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
.permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
JdbcUserDetailsManager userDetailsService = new JdbcUserDetailsManager();
userDetailsService.setDataSource(datasource);
PasswordEncoder encoder = new BCryptPasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
auth.jdbcAuthentication().dataSource(datasource);
auth.userDetailsService(userDetailsService);
if(!userDetailsService.userExists("user")) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("USER"));
User userDetails = new User("user", encoder.encode("password"), authorities);
userDetailsService.createUser(userDetails);
}
}
}
I am not getting any compilation errors but while running error is coming.
Please help me to resolve this issue .This is the only place i am stuck , if there are any documentation regarding spring boot security please tell me.