hi how i can use this orders for my controller and restController ....
like -> order 1 for html view and order 2 for rest api
i want use it for webapp using rest and mvc in spring
Multiple Entry Points With Multiple HTTP Elements
i think i should using order in my controller class!
#Configuration
#EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Configuration
#Order(1)
public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/user/**").hasRole("EMPLOYEE")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/LoginPage")
.loginProcessingUrl("/authenticateTheUser")
.successHandler(customAuthenticationSuccessHandler)
.permitAll()
.and()
.logout().permitAll() `enter code here`
.and()
.exceptionHandling().accessDeniedPage("/access-denied");
}
}
#Configuration
#Order(2)
public class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(m.authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/**").hasRole("EMPLOYEE")
.and()
.httpBasic()
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
}
i work on this problem and find way for using spring rest api and spring mvc in single
project this is easy to use them in one project with out security
for spring rest security and spring mvc security with login page and rest basic auth registery in a project we should use httpBasic()
and for url use
http://username:password#localhost:8080/api/members/
#Configuration
#EnableWebSecurity
public class MultipleEntryPointsSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserService userService;
#Autowired
private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
// this is filter for mappings for api and mvc mappings
// http://username:password#localhost:8080/api/members/
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").hasRole("EMPLOYEE")
.antMatchers("/leaders/**").hasRole("MANAGER")
.antMatchers("/systems/**").hasRole("ADMIN")
.antMatchers(HttpMethod.GET, "/api/**").hasRole("EMPLOYEE")
.and()
.httpBasic()
.and()
.formLogin()
.loginPage("/showMyLoginPage")
.loginProcessingUrl("/authenticateTheUser")
.successHandler(customAuthenticationSuccessHandler)
.permitAll()
.and()
.logout().permitAll()
.and()
.exceptionHandling().accessDeniedPage("/access-denied");
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
auth.setUserDetailsService(userService); //set the custom user details service
auth.setPasswordEncoder(passwordEncoder()); //set the password encoder - bcrypt
return auth;
}
}
Related
I have the below configuration where i need to configure HTTPBasic authentication for /api/v1/** endpoints and i want to configure form authentication for /users/ url pattern. When i run with the below configuration, the configuration for web requests is working correctly but the configuration for API is not working. No security is being applied. Where am I going wrong?
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
#Order(1)
#Configuration
public static class MVCSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
antMatcher("/users/**")
.csrf()
.and()
.authorizeRequests()
.antMatchers(
"/resources/**", "/users/register", "/users/signup", "/users/confirm", "/users/user-action", "/users/reset-password", "/confirm", "/webjars/**")
.permitAll()
.antMatchers("/users/**")
.hasRole("USER")
.anyRequest()
.authenticated()
.and()
.formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password");
http
.authorizeRequests()
.antMatchers("/api/v1/users/**")
.hasRole("USER")
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
}
I have put your code to work with this configuration bellow:
#EnableWebSecurity
public class SecurityConfiguration {
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/v1/users/**")
.authorizeRequests().anyRequest()
.hasRole("USER").and().httpBasic();
}
}
#Configuration
#Order(2)
public class MVCSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().and().authorizeRequests()
.antMatchers("/resources/**", "/users/register", "/users/signup", "/users/confirm",
"/users/user-action", "/users/reset-password", "/confirm", "/webjars/**").permitAll()
.antMatchers("/users/**").hasRole("USER")
.and()
.formLogin().usernameParameter("username").passwordParameter("password");
}
}
}
View docs for Spring Security and sample code here.
My Spring security works well but after some afk time I start getting tons of exceptions when the user goes to the pages.
I noticed that session and principal is null that's why I get error 500.
How do I redirect the user that to the login again?
Or I can simply remove the session timeout (i dont really need it)
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled=true)
#ComponentScan("pt.impactzero.atp")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private MyUserDetailsService myUserDetailsService;
#Autowired
private AuthenticationSuccessHandler authenticationSuccessHandler;
#Autowired
private LogoutSuccessHandler logoutSuccessHandler;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/").hasAnyRole("Administrator" , "Member")
.and()
.formLogin()
.loginPage("/login").permitAll()
.defaultSuccessUrl("/dashboard",true)
.failureUrl("/login?error")
.successHandler(authenticationSuccessHandler)
.and()
.logout()
.logoutUrl("/logout").permitAll()
.logoutSuccessUrl("/login")
.logoutSuccessHandler(logoutSuccessHandler)
.and()
.csrf().disable();
}
#Override
public void configure(WebSecurity web) {
web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder;
}
#Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
#Bean
public CommonsMultipartResolver filterMultipartResolver(){
return new CommonsMultipartResolver();
}
//Online users
#Bean
public ActiveUsers activeUsers(){
return new ActiveUsers();
}
}
If you want disable session, you can:
#Override
protected void configure(HttpSecurity http) throws Exception {
// disable session
http.sessionManagement().disable()
.authorizeRequests().antMatchers("/").hasAnyRole("Administrator" , "Member")
.and()
.formLogin()
.loginPage("/login").permitAll()
.defaultSuccessUrl("/dashboard",true)
.failureUrl("/login?error")
.successHandler(authenticationSuccessHandler)
.and()
.logout()
.logoutUrl("/logout").permitAll()
.logoutSuccessUrl("/login")
.logoutSuccessHandler(logoutSuccessHandler)
.and()
.csrf().disable();
}
if you want redirect user to login page, you can try this:
#Override
protected void configure(HttpSecurity http) throws Exception {
// redirect user to login page
http.sessionManagement().invalidSessionUrl("http://your.login.page").and()
.authorizeRequests().antMatchers("/").hasAnyRole("Administrator" , "Member")
.and()
.formLogin()
.loginPage("/login").permitAll()
.defaultSuccessUrl("/dashboard",true)
.failureUrl("/login?error")
.successHandler(authenticationSuccessHandler)
.and()
.logout()
.logoutUrl("/logout").permitAll()
.logoutSuccessUrl("/login")
.logoutSuccessHandler(logoutSuccessHandler)
.and()
.csrf().disable();
}
There are several references of multiple authentication providers in spring security, but no example in Java config could be located.
The following link gives the XML notation:
Multiple Authentication Providers in Spring Security
We need to authenticate using LDAP or DB
Below is our sample code:
#Configuration
#EnableWebSecurity
public class XSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationProvider authenticationProvider;
#Autowired
private AuthenticationProvider authenticationProviderDB;
#Override
#Order(1)
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
#Order(2)
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProviderDB);
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/scripts/**","/styles/**","/images/**","/error/**");
}
______
#Override
#Order(1)
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/","/logout","/time").permitAll()
.antMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/index")
.loginProcessingUrl("/perform_login")
.usernameParameter("email")
.passwordParameter("password")
.failureUrl("/index?failed=true")
.defaultSuccessUrl("/summary",true)
.permitAll()
.and()
.logout().logoutUrl("/logout")
.logoutSuccessUrl("/index?logout=true").permitAll()
.and()
.exceptionHandling().accessDeniedPage("/error403")
.and().authenticationProvider(authenticationProvider);
}
#Order(1)
protected void configureDB(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/","/logout").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/index")
.loginProcessingUrl("/perform_login")
.usernameParameter("email")
.passwordParameter("password")
.failureUrl("/index?failed=true")
.defaultSuccessUrl("/summary",true)
.permitAll()
.authenticationProvider(authenticationProviderDB)
//This line giving compilation error stating authenticationProvider is not available in formloginconfigurer
.and()
.logout().logoutUrl("/logout")
.logoutSuccessUrl("/index?logout=true").permitAll()
.and()
.exceptionHandling().accessDeniedPage("/error403");
}
}
May be this will help you :-
#Configuration
#EnableWebSecurity
#Profile("container")
public class XSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationProvider authenticationProvider;
#Autowired
private AuthenticationProvider authenticationProviderDB;
#Override
#Order(1)
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
#Order(2)
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProviderDB);
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/scripts/**","/styles/**","/images/**","/error/**");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/rest/**").authenticated()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.successHandler(new AuthenticationSuccessHandler() {
#Override
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication a) throws IOException, ServletException {
//To change body of generated methods,
response.setStatus(HttpServletResponse.SC_OK);
}
})
.failureHandler(new AuthenticationFailureHandler() {
#Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException ae) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
})
.loginProcessingUrl("/access/login")
.and()
.logout()
.logoutUrl("/access/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
#Override
public void onLogoutSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication a) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
})
.invalidateHttpSession(true)
.and()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.and()
.csrf()//Disabled CSRF protection
.disable();
}
}
In Spring Boot this worked for me:
Each Authentication provider is tested in order. If one passes, then its following Authentication providers are skipped
auth.userDetailsService(userDetailsService)...
then:
auth.ldapAuthentication()....
#EnableRedisHttpSession
#Configuration
#EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomUserDetailsService userDetailsService;
#Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
//each Authentication provider is tested in order
//if one passes then its following Authentication providers are skipped
//DataBase Authentication
auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
LdapContextSource ldapContextSource = new LdapContextSource();
ldapContextSource.setUrl("ldap://192.168.XXX.XXX:389");
ldapContextSource.setBase("dc=companyname,dc=com");
ldapContextSource.setUserDn("cn=user,cn=testgroup,ou=Test,dc=companyname,dc=com");
ldapContextSource.setPassword("user1234");
ldapContextSource.afterPropertiesSet();
//LDAP Authentication
auth.ldapAuthentication()
//The {0} in the (uid={0}) will be replaced by the username entered in the form.
.userSearchBase("ou=Group")
.userSearchFilter("uid={0}")
//.userDnPatterns("uid={0},ou=people")//does the same thing
//Specifies where the search for Roles start
//.groupSearchBase("ou=mathematicians")
//in groups we search for member
//.groupSearchFilter("member={0}")
//.contextSource().ldif("classpath:test-server.ldif");
.contextSource(ldapContextSource);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/hello").access("hasRole('ROLE_ADMIN')")
.antMatchers("/index").fullyAuthenticated()
.antMatchers("/").fullyAuthenticated()
.antMatchers("/home").fullyAuthenticated()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.usernameParameter("username").passwordParameter("password")
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.csrf()
.disable();
}
#Bean(name = "passwordEncoder")
public PasswordEncoder passwordencoder() {
return new BCryptPasswordEncoder();
}
}
This is a successful configuration which helps configure multiple authentication providers in java config.
Thanks a lot ojus for your inputs. It did help in nailing down the issue.
The key is to have
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
auth.authenticationProvider(authenticationProviderDB);
}
Full code below
#Configuration
#EnableWebSecurity
public class XSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private LDAPAuthenticationProvider authenticationProvider;
#Autowired
private DBAuthenticationProvider authenticationProviderDB;
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/scripts/**","/styles/**","/images/**","/error/**");
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
auth.authenticationProvider(authenticationProviderDB);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/","/logout").permitAll()
.antMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/index")
.loginProcessingUrl("/perform_login")
.usernameParameter("user")
.passwordParameter("password")
.failureUrl("/index?failed=true")
.defaultSuccessUrl("/test",true)
.permitAll()
.and()
.logout().logoutUrl("/logout")
.logoutSuccessUrl("/index?logout=true").permitAll()
.and()
.exceptionHandling().accessDeniedPage("/error");
}
}
I am using Spring Boot 1.5.9 and have an application that has an API that uses OAuth2 client credentials, with formlogin for a CMS that uses Thymeleaf in the same Spring Boot application.
For this to work, I have the following bean to configure the form login:
#Configuration
public class WebSecurityGlobalConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// api security is handled elsewhere (See OAuth2ServerConfiguration)
.antMatchers("/api/**", "/oauth/**", "/management/**")
.permitAll()
// end api security
.anyRequest().hasRole(UserRole.ADMIN.name())
.and()
.formLogin().loginPage("/login")
.permitAll()
.and()
.logout().permitAll();
}
}
So for the form login part, I declare everything related to API, Oauth and /management (the custom context-path I have set in application.properties for the actuator endpoints):
management.context-path=/management
management.security.roles=ADMIN
For Oauth2, I have this:
#Configuration
public class OAuth2ServerConfiguration {
private static final String RESOURCE_ID = "my-app-service";
#Configuration
#EnableResourceServer
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/api/**")
.permitAll()
.and()
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.authorizeRequests()
.antMatchers("/management/health", "/management/info").permitAll()
.antMatchers("/management/**").hasRole(UserRole.ADMIN.name())
.anyRequest().authenticated();
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private TokenStore tokenStore;
#Autowired
private SecurityConfiguration securityConfiguration;
// NOTE: If you set a new validity, you need to clear the 'oauth_access_token' table
// in the database. Only new tokens get the new validity.
#Value("${myapp.security.oauth.access-token-validity-seconds:43200}") // 12 hours by default
private int accessTokenValiditySeconds;
#Value("${myapp.security.oauth.refresh-token-validity-seconds:2592000}") // 30 days by default
private int refreshTokenValiditySeconds;
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.passwordEncoder(passwordEncoder);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(securityConfiguration.getMobileAppClientId())
.authorizedGrantTypes("password", "refresh_token")
.scopes("mobile_app")
.resourceIds(RESOURCE_ID)
.accessTokenValiditySeconds(accessTokenValiditySeconds)
.refreshTokenValiditySeconds(refreshTokenValiditySeconds)
.secret(passwordEncoder.encode(securityConfiguration.getMobileAppClientSecret()));
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).
authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
}
}
I want the following behaviour:
If user has role ADMIN by using an Oauth2 access token, all actuator endpoints must be accessible
If the user does not have this ADMIN role, only /health and /info should be accessible (If ADMIN, /health should show extra info like it is by default)
The current behaviour:
The info and health endpoints can be viewed by everybody, but as ADMIN, you don't get extra info. For the other endpoints, I get a 401 if I try with an access token of an ADMIN user with:
{
"timestamp": "2018-01-30T13:45:26.625+0000",
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource.",
"path": "/management/beans"
}
If I set management.security.enabled=false then the ADMIN user has access, but all non-ADMIN users also have access.
What should I change to get the wanted behaviour?
I managed to make it work with the following in the configure method of ResourceServerConfiguration :
http
.requestMatchers()
.antMatchers("/api/**")
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/api/**")
.permitAll()
.and()
.requestMatchers()
.antMatchers("/api/**")
.and()
.authorizeRequests()
.and()
.requestMatchers()
.antMatchers("/management/**")
.and()
.authorizeRequests()
.antMatchers("/management/health", "/management/info").permitAll()
.antMatchers("/management/**").hasRole(UserRole.ADMIN.name())
.anyRequest()
.authenticated()
Using multiple antMatchers directly on the http object does not work, you need to first use requestMatchers
So I have a two login pages. One for Customer and one for AM. I configured 2 login pages in my WebSecurityConfig class. When I try to login in AM using an admin account it works but when I try to login in Customer using a user account the loginProcessingUrl can't be found.
In my WebSecurityConfig class:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig
{
#Autowired
MyDBAuthenticationService myDBAuthenticationService;
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(myDBAuthenticationService);
}
#Configuration
#Order(1)
public static class WebConfigurationAdapter1 extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests().antMatchers("/am/**").access("hasRole('ROLE_AM')")
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.formLogin()
.loginPage("/amLogin")
.loginProcessingUrl("/am/postLogin")
.defaultSuccessUrl("/amChatPage")
.failureUrl("/amLogin?error")
.and().logout().logoutUrl("/amLogout").logoutSuccessUrl("/amLogoutSuccessful")
.deleteCookies("JSESSIONID")
.and().csrf().disable();
System.out.println("1st Configurer");
}
}
#Configuration
#Order(2)
public static class WebConfigurationAdapter2 extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests().antMatchers("/customer/**").access("hasRole('ROLE_CUSTOMER')")
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.formLogin()
.loginPage("/customerLogin")
.loginProcessingUrl("/customer/postLogin")
.defaultSuccessUrl("/customerChatPage")
.failureUrl("/customerLogin?error")
.and().logout().logoutUrl("/customerLogout").logoutSuccessUrl("/customerLogoutSuccessful")
.and().csrf().disable();
System.out.println("2nd Configurer");
}
}
}
Here's my SpringWebAppInitializer class:
#Configuration
public class SpringWebAppInitializer implements WebApplicationInitializer{
#Override
public void onStartup(ServletContext sc) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(ApplicationContextConfig.class);
ServletRegistration.Dynamic dispatcher = sc.addServlet("dispatcher", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
Things that I have done so far are:
Putting sout() in each static class to know if it gets run. Both did display the sout().
Change name of both processing url and make it unique. Also change in my jsp file.
Spring boot - how to configure multiple login pages?
Here is the result when I login as AM:
Result in netbeans. It enters the Controller but says "null"
Here is the result when I login as Customer:
Since there is no differentiation pattern between both http configuration Spring Security is taking the first one login as default, that is the reason why only admin login works, because it is part of the web security adapter declared as Order(1).
In order to separate both configuration properly it is necessary to define a pattern separation with .antMatcher.
here is one small example to give you an idea of how define both configuration
For admins (see the .antMatcher definition it forces to apply the http configuration only to admin/** urls.
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.antMatcher("/admin/**").authorizeRequests().anyRequest().authenticated().anyRequest().hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/adminLogin")
.loginProcessingUrl("/admin/postLogin")
.defaultSuccessUrl("/admin/home")
.failureUrl("/adminLogin?error")
.and().logout().logoutUrl("/admin/logout").logoutSuccessUrl("/home")
.and()
.csrf().disable();
}
For customers (see the .antMatcher definition it forces to apply the http configuration only to customer/** urls.
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.antMatcher("/customer/**").authorizeRequests().anyRequest().authenticated().anyRequest().hasRole("USER")
.and()
.formLogin()
.loginPage("/customerLogin")
.loginProcessingUrl("/customer/postLogin")
.defaultSuccessUrl("/customer/home")
.failureUrl("/customerLogin?error")
.and()
.logout().logoutUrl("/customer/logout").logoutSuccessUrl("/home")
.and()
.csrf().disable();
}
There are other examples here: Example two login pages and visit the spring security documentation Multiple Http Security
Hope this information helps you.
According to the new configuration you have to do some changes, please review the following configuration, and compare with yours and you will see what is the difference (antMatcher is different of antMatchers)
#Configuration
#EnableWebSecurity
public class WebSecurityConfig
{
#Autowired
MyDBAuthenticationService myDBAuthenticationService;
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(myDBAuthenticationService);
}
#Configuration
#Order(1)
public static class WebConfigurationAdapter1 extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
//.authorizeRequests().antMatchers("/am/**").access("hasRole('ROLE_AM')")
.antMatcher("/am/**").authorizeRequests().anyRequest().hasRole("AM")
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.formLogin()
.loginPage("/amLogin")
.loginProcessingUrl("/am/postLogin")
.defaultSuccessUrl("/am/chatPage")
.failureUrl("/amLogin?error")
.and().logout().logoutUrl("/am/logout").logoutSuccessUrl("/amLogoutSuccessful")
.deleteCookies("JSESSIONID")
.and().csrf().disable();
System.out.println("1st Configurer");
}
}
#Configuration
#Order(2)
public static class WebConfigurationAdapter2 extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
//.authorizeRequests().antMatchers("/customer/**").access("hasRole('ROLE_CUSTOMER')")
.antMatcher("/admin/**").authorizeRequests().anyRequest().hasRole("CUSTOMER")
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.formLogin()
.loginPage("/customerLogin")
.loginProcessingUrl("/customer/postLogin")
.defaultSuccessUrl("/customer/chatPage")
.failureUrl("/customerLogin?error")
.and().logout().logoutUrl("/customer/logout").logoutSuccessUrl("/customerLogoutSuccessful")
.and().csrf().disable();
System.out.println("2nd Configurer");
}
}
}
And finally remember the controller, you should have the following RequestMapping definition at least
#RequestMapping("/adminLogin"), #RequestMapping("/customerLogin"), #RequestMapping("/am/chatPage"), #RequestMapping("/customer/chatPage")