Hi i tried to get userDetailsService with InMemoryDao. But i can't get it, i tried #Autowired, #Inject (UserDetailsService, InMemoryDaoImpl, InMemoryManager...) but cant get this working.
Have public class Security extends WebSecurityConfigurerAdapter and public class GlobalSecurity extends GlobalAuthenticationConfigurerAdapter.
Tried with only WebSecurityConfigurerAdapter with all four #Enable...
Can some help me to solve this, i need to use loadUserByUsername()?
You can expose the userDetailsService bean by overriding method userDetailsServiceBean() in your configuration class which extends WebSecurityConfigurerAdapter. The whole method will look like this:
#Bean(name = "myUserDetailsService")
#Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
And then you can inject it for example with #Autowired.
Related
With Spring Security <5.2
In a legacy project, for a password grant scenario, I need to configure an authorization server.
Currently it is done extending AuthorizationServerConfigurerAdapter, and the authorization endpoints are configured overriding the configure(AuthorizationEndpointsServerConfigurer) method.
My problem is that this configurer takes one AuthenticationManager for the password grant, when I would need something like an AuthenticationManagerResolver (but I can't upgrade to 5.2) to be able to apply a different authentication depending on the incoming URL (an authentication manager for admin URLs, e.g. "/admin/**", and another one for non-admin).
How can I do that? I can change the approach, but again I can't upgrade.
You can try implementing your own DelegatingAuthenticationManager, inject the list of your AuthenticationManagers in it, and put your logic in authenticate method. E.g:
#Component("delegatingAM")
public class DelegatingAuthenticationManager implements AuthenticationManager {
private final List<AuthenticationManager> ams;
#Autowire
public DelegatingAuthenticationManager(#Qualifier("x") AuthenticationManager amX, #Qualifier("y") AuthenticationManager amY) {
this.ams = List.of(amX, amY); // Arrays.asList(amX, amY);
// you can inject variables for your conditions here
}
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (...) this.ams.get(0).authenticate(authentication);
if (...) this.ams.get(0).authenticate(authentication);
// Or you can loop over the list like AuthenticationManager is implemented with AuthenticatioProvider
}
}
Then inject it to AuthorizationServerConfigurerAdapter
#Configuration
#EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("delegatingAM")
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.authenticationManager(this.authenticationManager)
}
...
}
Hope it will help, for the worse case, you could start to think about using many AuthorizationServerSecurityFilterChains, one AuthenticationManager for each. And based on the URL, direct the request to the right SecurityFilterChain.
I am receiving a Request method 'POST' not supported error when I #EnableOAuth2Sso on my Spring Boot 1.5.9 / Angular 5 app.
GET requests work fine, and the JSESSIONID cookie looks like it's setting itself just fine on the front-end. Cookie is getting passed with all requests, and matches.
In the Response Header: Status Code: 405 Allow: GET, HEAD
This is my first Stack Overflow question, I've done all of my usual sleuthing and can't seem to get to the bottom of this one. I apologize in advance for any oversights in my asking / formatting of this question.
#SpringBootApplication
#EnableOAuth2Sso
#EnableOAuth2Client
public class CompanyApplication {
public static void main(String[] args) {
SpringApplication.run(CompanyApplication.class, args);
}
}
Relevant Controller
#RestController
#RequestMapping("api")
public class CompanyController {
#Autowired
CompanyRepository companyRepository;
#Autowired
ContactRepository contactRepository;
#PostMapping("companies")
public Company createCompany(#Valid #RequestBody Company company) {
logger.info("*** Starting POST request of company name: {}", company.getName());
company = updateContacts(company); // pass updated contact info into the Contact DB
companyRepository.save(company);
logger.info("*** Successful POST request of company: {}, ID: {},", company.getName(), company.getId());
return company;
}
Config settings:
security.oauth2.client.clientId=myID
security.oauth2.client.clientSecret=mySecret
security.oauth2.client.accessTokenUri=https://myserver.com/connect/token
security.oauth2.client.userAuthorizationUri=https://myserver.com/connect/authorize
security.oauth2.client.scope=openid,profile,email
security.oauth2.resource.userInfoUri=https://myserver.com/connect/userinfo
Angular service:
public updateCompany( companyData: Company ) {
return this.http.post(this.url, companyData);
}
Edit:
I followed the advice of #theLearner below, but still wanted to add CSRF (XSRF) protection. This is how I ended up doing it:
In app.module.ts add HttpClientXsrfModule to imports (I'm on Angular 5).
Remove #EnableOAuth2Sso from root CompanyApp class.
Config as follows:
#Configuration
#EnableOAuth2Sso
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().anyRequest().authenticated().
and().
csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
There are following things you need to do.
In application properties add this config:
security.oauth2.resource.filter-order=3
More info about this is here.
Since you have not posted your Spring security config yet, not sure how is it right now. But it should look like this:
#Configuration
#EnableOAuth2Sso
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable() // or replace this with tour csrf token repository
.authorizeRequests()
.anyRequest().authenticated();
}
This SO post explains if #EnableOauth2Sso is not used carefully it can really mess up entire security configuratiin
I am new to spring security and I am trying to build a restful API based sample Spring Security based example and I have used Spring Boot to create project.But I am getting following error when I send a request url:-
Request Url:-
http://localhost:8080/message
Response Got: -
{"timestamp":1505139451257,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/message"}
The Below is the code I have added:-
1] Main Class
#SpringBootApplication
#ComponentScan("com.srikss.controller")
public class SrikSsApplication {
public static void main(String[] args) {
SpringApplication.run(SrikSsApplication.class, args);
}
Controller:-
#RestController
public class HelloWorldController {
#RequestMapping(value="/message",method=RequestMethod.GET,headers="Accept=application/json")
public String messageLoad()
{
return "hello";
}
}
Configuration Class: -
#Configuration
#EnableWebSecurity
public class SrikSSConfiguration extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity httpsecurity) throws Exception
{
httpsecurity.authorizeRequests().anyRequest().permitAll().and()
.httpBasic();
httpsecurity.csrf().disable();
}
}
Can anyone help me to figure out what I am doing wrong here.
Thanks in advance.
Finally got the reason what I was doing wrong.
with the help of this reference link:-
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-security.html
actually spring boot defines default password which generated randomly and the default user name is "user".
After I update the password in application.properties file got the desired result,
security.user.password=aaa
I have a rest webservice configured as a spring boot application.
All my rest urls have a base path "/api/...".
I am also serving static content from my application.
I need to configure security ONLY for the web service i.e., URLs that start with "/api/..." but give the other static content w/o applying security.
I've only seen examples where we filter some url patterns via:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/*");
}
but not otherwise ...
Use the antMatcher method of HttpSecurity class:
#Configuration
#EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**");
// add security constraints for /api/... here
}
/* rest of config */
}
Instead of antMatcher, you can you regexMatcher wich can be a negation pattern
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().regexMatchers(XXXXX);
}
Answer to your last comment, if you are using latest spring framework and spring security then define below class and security config as per the config standards.
package org.springframework.security.samples.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class MessageSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
Also, look at below URL if you still find it difficult to get started with spring security.
http://docs.spring.io/spring-security/site/docs/3.2.6.RELEASE/reference/htmlsingle/#hello-web-security-java-configuration
I am trying to implement a Spring Boot version of Pet Clinic overriding as little of Spring Boot defaults as possible.
At this point, my logout link doesn't seem to work and I've been told that it is because I haven't properly added HttpSessionEventPublisher to my application.
How can I add HttpSessionEventPublisher to my application?
I've tried the following:
#Component
#Configuration
public class WebXmlConfig implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addListener(new HttpSessionEventPublisher());
}
}
and
#Bean
public ServletListenerRegistrationBean<HttpSessionEventPublisher> getHttpSessionEventPublisher() {
return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(new HttpSessionEventPublisher());
}
My main class does not extend any classes. If that is required for me to add HttpSessionEventPublisher, I would need to know which class also.
None of the Spring Boot examples log out properly, so I have nothing to based on off of.
Any help would be appreciated.