How to protect AngularJS partials pages with Spring Security - java

I'm working on a Spring MVC web app and I'm using AngularJS, I want to protect my views based on roles, example if I login with and admin role I can watch the delete users partial page, and if I login with user role I can't watch the delete user partial page.
I knew how to do this with spring security but with a normal web app not with a restful Single page app with angularJS, since with angular you are not really requesting a view from the server instead you just load a partial html page in a ng-view tag.
I'm also using ngRoute to route my partials.
Here is my ngRoute.jS file
angular.module('MyApp')
.config(['$routeProvider', 'USER_ROLES' ,function ($routeProvider, USER_ROLES) {
$routeProvider.
when('/', {
templateUrl: '/SpringMVCTemplateAnn/resources/angular/templates/dashboardTemplates/dashboardTemplate.html',
controller: 'DashBoardCtrl',
access: {
loginRequired: true,
authorizedRoles: [USER_ROLES.all]
}
}).
when('/login', {
templateUrl: '/SpringMVCTemplateAnn/resources/angular/templates/loginTemplate/login.html',
controller: 'LoginController',
access: {
loginRequired: false,
authorizedRoles: [USER_ROLES.all]
}
}).
when('/createUser', {
templateUrl: '/SpringMVCTemplateAnn/views/partials/userTemplates/createUser.html',
controller: 'UserCtrl'
}).
when('/deleteUser', {
templateUrl: '/SpringMVCTemplateAnn/views/partials/userTemplates/deleteUser.html',
controller: 'UserCtrl'
}).
}]);
here is my spring security configuration I'm using java annotation configuration, I have adapted the configuration to convert it so it could fit a rest application
this is my Security class that extends WebSecuirtyConfigureAdapter
public class SegurityConfig extends WebSecurityConfigurerAdapter {
public SegurityConfig() {
super();
}
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private RestUnauthorizedEntryPoint restAuthenticationEntryPoint;
#Autowired
private AccessDeniedHandler restAccessDeniedHandler;
#Autowired
private AuthenticationSuccessHandler restAuthenticationSuccessHandler;
#Autowired
private AuthenticationFailureHandler restAuthenticationFailureHandler;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**", "/index.jsp", "/login.jsp",
"/template/**", "/", "/error/**");
}
//
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().disable()
.csrf().disable()
.authorizeRequests()
.antMatchers("/failure").permitAll()
.antMatchers("/v2/api-docs").hasAnyAuthority("admin")
.antMatchers("/users/**").hasAnyAuthority("admin")
.antMatchers("/views/partials/userTemplates/createUser.html").access("hasRole('create users')")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.accessDeniedHandler(restAccessDeniedHandler)
.and()
.formLogin()
.loginProcessingUrl("/login")
.successHandler(restAuthenticationSuccessHandler)
.failureHandler(restAuthenticationFailureHandler)
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
.deleteCookies("JSESSIONID")
.permitAll()
.and();
}
}
I'm also using the http-auth-interceptor plugin for angularjs
here is MyApp module
angular.module('MyApp', ['ngRoute', 'ui.bootstrap', 'smart-table', 'http-auth-interceptor']);
and here is my js file that prevents users for navigating the site without being authenticated
angular.module('MyApp')
.run(function ($rootScope, $location, $http, AuthSharedService, Session,
USER_ROLES, $q, $timeout) {
$rootScope.$on('$routeChangeStart', function (event, next) {
if (next.originalPath === "/login" && $rootScope.authenticated) {
event.preventDefault();
console.log('registrese');
} else if (next.access && next.access.loginRequired && !$rootScope.authenticated) {
event.preventDefault();
$rootScope.$broadcast("event:auth-loginRequired", {});
} else if (next.access && !AuthSharedService.isAuthorized(next.access.authorizedRoles)) {
event.preventDefault();
$rootScope.$broadcast("event:auth-forbidden", {});
}
});
// Call when the the client is confirmed
$rootScope.$on('event:auth-loginConfirmed', function (event, data) {
console.log('login confirmed start ' + data);
$rootScope.loadingAccount = false;
var nextLocation = ($rootScope.requestedUrl ? $rootScope.requestedUrl : "/home");
var delay = ($location.path() === "/loading" ? 1500 : 0);
$timeout(function () {
Session.create(data);
$rootScope.account = Session;
$rootScope.authenticated = true;
$location.path(nextLocation).replace();
}, delay);
});
// Call when the 401 response is returned by the server
$rootScope.$on('event:auth-loginRequired', function (event, data) {
if ($rootScope.loadingAccount && data.status !== 401) {
$rootScope.requestedUrl = $location.path()
$location.path('/loading');
} else {
Session.invalidate();
$rootScope.authenticated = false;
$rootScope.loadingAccount = false;
$location.path('/login');
}
});
// Call when the 403 response is returned by the server
$rootScope.$on('event:auth-forbidden', function (rejection) {
$rootScope.$evalAsync(function () {
$location.path('/error/403').replace();
});
});
});
and here is my USER_ROLES constant js file
angular.module('MyApp')
.constant('USER_ROLES', {
all: '*',
admin: 'admin',
user: 'user'
});
I want to protect my partials pages if I login with a user that have the normal user role I want to be able to not watch the delete or create users partial page,
I tried moving my partials outside of the resources folder and putting this in my secuirty class .antMatchers("/views/partials/userTemplates/createUser.html").access("hasRole('create users')") but what this does if that it blocks the partial even if I login with a user that have that role I still get the 403 error, I would like to this to happen but if I login with a user that doesn't have that role but why this happens when I login with a user that have the role is like it doesn't recognize that I have that role.
Is there a way to protect those partials based on roles like in a normal web app because that config worked in a normal web app that I worked but it looks like it doesn't work in a Single page rest app.
If it possible to protect those partials from the server side, I know that I can protect my Rest methods in the server-side using #PreAuthorize("hasRole('create users')") but is there a way to put like an .antMatchers("/my partials/**").hasAnyAuthority("admin") or something similar in the security config class to protect the partials?
My folder structure
SpringMVCProject
--Web-Pages
--WEB-INF
--resources
--angular
--controllers
userController.js
--services
userService.js
--partials
--userPartials
deleteuser.html
app.js
permissionConstants.js
routes.js
--css
--views
--partials (I experimented putting this the folder but I 403 error)
--userpartials
deleteuser.html
index.html
--Source Packages
--controllers
--userControllers
UserController.java
--secuirty
SecuirtyConfig.java

Related

Spring security on endpoint using Cognito IAM role?

I am trying to restrict specific endpoints on a Spring boot service depending on what role they have set in the OAuth2 credentials.
This is the endpoint
#RestController
#RequestMapping("/api/admin")
public class AdminController {
#GetMapping(produces = "application/json")
public TestResponse get() {
return new TestResponse("Admin API Response");
}
}
This is then secured using SecurityConfiguration bean
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.and()
.authorizeRequests()
.antMatchers("/login", "/", "/home", "/logout", "/ping").permitAll()
.antMatchers("/api/admin").hasRole("arn:aws:iam::xxxxxx:role/spring-sso-test-ADMIN")
.antMatchers("/api/user").hasRole("arn:aws:iam::xxxxxx:role/spring-sso-test-USER")
.and()
.oauth2Login()
.and()
.logout()
.logoutSuccessUrl("/logout");
}
}
I debugged the Principal and can see the correct IAM role in the list of attributes cognito:roles list
However when I hit the endpoint I get a HTTP 403 Unauthorized. Meaning that the user has authenticated successfully, but Spring does not recognize or understand the attributes or how to map them?
I tried using the #Secured annotation but that didn't change anything.
#Secured("arn:aws:iam::xxxxxx:role/spring-sso-test-ADMIN")
#GetMapping(produces = "application/json")
public TestResponse get() {
return new TestResponse("Admin API Response");
}
How do I allow this to work using an IAM role defined in AWS Cognito?
When you use the hasRole DSL method, Spring Security adds the ROLE_ prefix to your authority. So, the authority arn:aws:iam::xxxxxx:role/spring-sso-test-ADMIN will become ROLE_arn:aws:iam::xxxxxx:role/spring-sso-test-ADMIN.
You should use the hasAuthority method instead.
Additionally, you should take the cognito:roles from the attributes and add in the authorities, since it's the property that Spring Security will query to get the authorities.
To map the authorities you can use a OAuth2UserService:
#Bean
SecurityFilterChain app(HttpSecurity http) throws Exception {
http
.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfo -> userInfo
.oidcUserService(this.oidcUserService())
...
)
);
return http.build();
}
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
// your custom implementation
}
More details in the documentation.

spring security HTTP Status 403 - Access Denied

Login is success but spring security blocking url even i given access to USER . How can i manage this thing?
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("sahil").password("123")
.roles("ADMIN","USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/welcome","/inventory/**","/sales/**").access("hasRole('USER')")
.and()
.csrf().disable();
}
LoginController.java
#Controller
public class LoginController {
#RequestMapping(value = { "/", "/login" }, method = RequestMethod.GET)
public String showLoginPage() {
return "login";
}
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String handleUserLogin(ModelMap model, #RequestParam String name, #RequestParam String password) {
if (!service.validateUser(name, password)) {
model.put("errorMsg", "Invalid Credential");
return "login";
}
System.out.println("principal : " + getLoggedInUserName());
model.put("name", name);
model.put("password", password);
return "welcome";
}
private String getLoggedInUserName() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
System.out.println("in if");
return ((UserDetails)principal).getUsername();
} else {
System.out.println("in else");
return principal.toString();
}
}
#RequestMapping(value = "/welcome", method = RequestMethod.GET)
public String showWelcomeDashboard() {
return "welcome";
}
}
1 . Once Login success page redirected to welcome page but url is still localhost:8080/login instead of localhost:8080/welcome.
2. After redirecting to URL localhost:8080/sales is it 403 Access denied.
What is spring security
Spring security is all about authentication and authorization, in your case you are missing authentication. There is no configuration of authentication in your security configuration. What you are missing is authentication filter for your spring security. Spring security provides default authentication filter UsernamePasswordAuthenticationFilter that can be configured by .formLogin(). You can use default provided or you can define your own custom authentication filter(Implementation of UsernamePasswordAuthenticationFilter).
Once authentication is success spring security will grant authorities for authenticated user. If authentication is configured correctly, below configuration is responsible for authentication and granting authority
auth.inMemoryAuthentication().withUser("sahil").password("123")
.roles("ADMIN","USER");
Authenticated users each request will be passed through filter FilterSecurityInterceptor and it will verifies authority granted for authenticated user with authorization configured for resources as given in below code.
.antMatchers("/welcome","/inventory/**","/sales/**").access("hasRole('USER')")
You missed all this by not configuring authentication filter.
Now for making it simple use.formLogin() in your http configuration.
#Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/welcome","/inventory/**","/sales/**").access("hasRole('USER')")
.and().exceptionHandling()
.accessDeniedPage("/403")
.and().formLogin()
.and().logout()
.logoutSuccessUrl("/login?logout=true")
.invalidateHttpSession(true)
.and()
.csrf()
.disable();
}
.formLogin() without any configuration provides default login page with username and password default form parameters.And after authentication it redirects to "/" If you want to provide your custom login page then use below configuration.
.and().formLogin()
.loginPage("/login")
.usernameParameter("email").passwordParameter("password")
.defaultSuccessUrl("/app/user/dashboard")
.failureUrl("/login?error=true")
.loginPage("") - Your custom login page URL
.usernameParameter("").passwordParameter("") - Your custom login form parameters
.defaultSuccessUrl("") - Page url after successful authentication
.failureUrl("") - Page url after authentication failure
Note: You should not use "/login" POST method in your controller, Even though if you write, it will not be reached from spring security filter chain. As your configuration was wrong before, it was reaching before! Now you remove those from your controller and use conventional approach as mentioned above.

Postman showing HTML instead of JSON

I have a simple Spring Boot + Spring Security REST app with quotations. Only 3 endpoints for GET, POST, DELETE. Only moderator and admin accounts defined. GET rest method works fine - it shows list of quotations. The problem is with POST and DELETE methods. When I try to invoke them in Postman it returns HTML (logging form defined in SecurityConfig).
QuotationApi.java
#RestController
public class QuotationApi {
private List<Quotation> quotations;
public QuotationApi() {
this.quotations = new ArrayList<>();
quotations.add(new Quotation("Those who dare to fail miserably can achieve greatly.", "John F. Kennedy"));
quotations.add(new Quotation("Get busy living or get busy dying.", "Stephen King"));
}
#GetMapping("/api")
public List<Quotation> getQuotation() {
return quotations;
}
#PostMapping("/api")
public boolean addQuotation(#RequestBody Quotation quotation) {
return quotations.add(quotation);
}
#DeleteMapping("/api")
public void deleteQuotation(#RequestParam int index) {
quotations.remove(index);
}
}
SecurityConfig.java
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// creating users
#Bean
public UserDetailsService userDetailsService() {
UserDetails moderator = User.withDefaultPasswordEncoder()
.username("user")
.password("user")
.roles("MODERATOR")
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("admin")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(moderator, admin);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.GET,"/api").permitAll()
.antMatchers(HttpMethod.POST,"/api").hasRole("MODERATOR")
.antMatchers(HttpMethod.DELETE,"/api").hasRole("ADMIN")
.anyRequest().hasRole("ADMIN")
.and()
.formLogin().permitAll()
.and()
.logout().permitAll()
.and()
.csrf().disable();
}
}
I have Basic_auth in Postman:
EDIT after Andreas's help (working code):
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.GET,"/api").permitAll()
.antMatchers(HttpMethod.POST,"/api").hasRole("MODERATOR")
.antMatchers(HttpMethod.DELETE,"/api").hasRole("ADMIN")
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic()
.and()
.formLogin().permitAll()
.and()
.logout().permitAll()
.and()
.csrf().disable();
}
Doesn't matter that Postman is sending Basic authentication header, when you haven't enabled Basic authentication in Spring.
Since you only called formLogin() to enable form based authentication, you have to login using the form POST.
Of course, you could just call httpBasic() to enable Basic authentication too.

Authorization of access to resources with spring security and Angularjs

I made permission to access resources in spring security as shown in this code: "The user authentication is then from the DB"
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
protected void globalConfig(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
//auth.inMemoryAuthentication().withUser("user").password("123").roles("USER");
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("select username as principal, password as credentials, etat as actived from utilisateurs where username=?")
.authoritiesByUsernameQuery("select u.username as principal, ur.nom_role as role from utilisateurs u inner join roles ur on(u.roles_id=ur.id_role) where u.username=?")
.rolePrefix("ROLE_");
}
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().maximumSessions(100).maxSessionsPreventsLogin(false).expiredUrl("/Login");
http
.authorizeRequests()
.antMatchers("/AppJS/**","/images/**","/pdf/**","/Template/**","/Views/**","/MainApp.js").permitAll()
.antMatchers("/Users/**").access("hasRole('ADMIN')")
.antMatchers("/Dashbord/**").access("hasRole('ADMIN')")
.antMatchers("/Login*").anonymous()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/Login").permitAll()
.defaultSuccessUrl("/home")
.failureUrl("/Login?error=true")
.and().exceptionHandling().accessDeniedPage("/Access_Denied")
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutUrl("/logout")
.permitAll()
.logoutSuccessUrl("/Login");
}
}
Subsequently, I specified the views for each URL:
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter{
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/Login").setViewName("Login");
registry.addViewController("/Dashbord").setViewName("home");
registry.addViewController("/logout").setViewName("Login");
registry.addViewController("/Users").setViewName("Views/ListUsers");
}
}
I used the angularJS routeProvider to keep track of URLs:
var app = angular.module('Mainapp', ['ngRoute','file-model','ui.bootstrap','ngMessages']);
app.config(function($routeProvider) {
$routeProvider
.when('/Users', {
controller:'UsersController',
templateUrl: 'Views/ListUsers'
})
.when('/Dashbord', {
controller: 'ResultController',
templateUrl: 'Views/home.html'
});
});
My problem is how to make the link of the access authorization that I
defined in spring security with the URLs of angularjs ($
routeProvider)
Thank you,
and Have a good day,
You could try enable html5mode, to get this
AngularJS: http://localhost:8080/Users
app.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/Users', {
controller:'UsersController',
templateUrl: 'Views/ListUsers'
})
.when('/Dashbord', {
controller: 'ResultController',
templateUrl: 'Views/home.html'
});
$locationProvider.html5Mode(true)
});
I am not sure this will meets your requirement but yes i have already did before with the use of ngPermission. Before that you need list of the roles to set in your route.
.state('view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl',
resolve: {
authorization: ["ngPermissionService", function (ngPermissionService) {
//you need to call webserivce at this level for get all user's permissions and return it.
return ngPermissionService.role(["admin"])
}]
}
});
For more details click here

Spring Security logout does not work - does not clear security context and authenticated user still exists

I know, there are many articles about this topic, but I have a problem and I can't find any solution.
I have a classic spring security java config:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuctionAuthenticationProvider auctionAuthenticationProvider;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(auctionAuthenticationProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic();
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequest = http.authorizeRequests();
configureAdminPanelAccess(authorizeRequest);
configureFrontApplicationAccess(authorizeRequest);
configureCommonAccess(authorizeRequest);
http.csrf()
.csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
http.logout()
.clearAuthentication(true)
.invalidateHttpSession(true);
}
...
}
Also, I have two controller methods, where I login/logout from my web application by AJAX.
When I would like to logout, I first call this method, which I expect to clear user sessions and clear everything from the security context.
#Override
#RequestMapping(value = "/logout", method = GET, produces = APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<Boolean> logout(final HttpServletRequest request, final HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null){
new SecurityContextLogoutHandler().logout(request, response, auth);
}
return new ResponseEntity<>(Boolean.TRUE, HttpStatus.OK);
}
After this I reload my client web application and each time, when it is reloaded, I check whether the user is authenticated by calling the following controller method:
#Override
#RequestMapping(value = "/user", method = GET, produces = APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<UserDetails> user() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
return new ResponseEntity<>((UserDetails) principal, HttpStatus.OK);
}
return null;
}
And here I aways receive the last authenticated user. It seems that in the previous logout method, Spring logout doesn't work.
Keep in mind that I tried to logout with the following code, without any success:
#Override
#RequestMapping(value = "/logout", method = GET, produces = APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<Boolean> logout(final HttpServletRequest request) {
try {
request.logout();
return new ResponseEntity<>(Boolean.TRUE, HttpStatus.OK);
} catch (ServletException ex) {
if (LOG.isDebugEnabled()) {
LOG.debug("There is a problem with the logout of the user", ex);
}
}
Are you have any idea what I miss in my config and the logout process?
From your question, I see you are trying to create your own logout and you also trying to use the default Spring logout. I advise that you should choose one method and not mix them both. There are two I recommend to logout from Spring:
First: Default spring security logout
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/logout.done").deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
From the example above, you should only need to call the /logout URL whenever you want to logout the user. No need to create any #Controller to handle that logout instead Spring will help to log the user out. You also can add other thing you want to invalidate here.
Second: Programmatically logout
#RequestMapping(value = {"/logout"}, method = RequestMethod.POST)
public String logoutDo(HttpServletRequest request,HttpServletResponse response){
HttpSession session= request.getSession(false);
SecurityContextHolder.clearContext();
session= request.getSession(false);
if(session != null) {
session.invalidate();
}
for(Cookie cookie : request.getCookies()) {
cookie.setMaxAge(0);
}
return "logout";
}
If you are using this logout approach, you don't need to include the first method in ht eSpring security config. By using this method, you can add an extra action to perform before and after logout done. BTW, to use this logout, just call the /logout url and the user will be logged out manually. This method will invalidate the session, clear Spring security context and cookies.
In addition for the second method, if you are using RequestMethod.POST, you need to include the CSRF key on the POST request. The alternative way is to create a form with a hidden input CSRF key. This is some example of auto generated logout link with jQuery :
$("#Logout").click(function(){
$form=$("<form>").attr({"action":"${pageContext.request.contextPath}"+"/logout","method":"post"})
.append($("<input>").attr({"type":"hidden","name":"${_csrf.parameterName}","value":"${_csrf.token}"}))
$("#Logout").append($form);
$form.submit();
});
You just need to create a hyperlink <a id="Logout">Logout</a> to use it.
If you are using RequestMethod.GET,just include a CSRF key as a parameter in you link like this:
Logout
Thats all, hope it helps.
Just a heads up, there is Clear Site Data HTTP header as shown below
Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"
I also helped add support for Clear-Site-Data header into Spring-Security 5.2 project. For more details around the implementation, see the PR.
Here is a sample of how it is going to work
#EnableWebSecurity
static class HttpLogoutConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.logout()
.addLogoutHandler(new HeaderWriterLogoutHandler(
new ClearSiteDataHeaderWriter(SOURCE)));
}
}
Where SOURCE is a vararg of one or more of the following
"*" Clear everything
One or more of "cache", "cookies", "storage", "executionContexts"
For more details see the sample test in the LogoutConfigurerClearSiteDataTests.java.
This will help, i think clearAuthentication(true) is enough:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
....
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.httpBasic()
.and()
.logout().clearAuthentication(true)
.logoutSuccessUrl("/")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.and()
I solved my problem similarly by adding the following parameter to the application.properties file
spring.cache.type=NONE
Just change logout URL from "/logout" to "war or snapshot name/logout"

Categories