I was following this tutorial with the only difference that I used Fetch API for querying REST repository. My problem is that after successful authorization every fetch() call returns response containing login form html string. Specifically, this kind of code
fetch(`${root}/employees?size=${pageSize}`).then( p => p.json()})
produces the following error in Chrome console:
localhost/:1 Uncaught (in promise) SyntaxError: Unexpected token < in
JSON at position 0
If I add a header with authorization to fetch:
fetch(`${root}/employees?size=${pageSize}`, {
method: 'GET',
headers: new Headers({'Content-Type': 'application/json',
'Authorization': 'Basic '+btoa('greg:turnquist'))})
all works, but this looks silly after all effort put in configuring Spring Security beans and for sure it is not the best practice.
All java sources remain the same as in tutorial but I include fragments from configuration classes here:
SecurityConfiguration.java
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private SpringDataJpaUserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(this.userDetailsService)
.passwordEncoder(Manager.PASSWORD_ENCODER);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/build/**", "/main.css").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/", true)
.permitAll()
.and()
.httpBasic()
.and()
.csrf().disable()
.logout()
.logoutSuccessUrl("/");
}
}
SpringDataJpaUserDetailsService.java
#Component
public class SpringDataJpaUserDetailsService implements UserDetailsService {
private final ManagerRepository repository;
#Autowired
public SpringDataJpaUserDetailsService(ManagerRepository repository) {
this.repository = repository;
}
#Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
Manager manager = this.repository.findByName(name);
return new User(manager.getName(), manager.getPassword(),
AuthorityUtils.createAuthorityList(manager.getRoles()));
}
}
EmployeeRepository.java
#PreAuthorize("hasRole('ROLE_MANAGER')")
public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long> {
#Override
#PreAuthorize("#employee?.manager == null or #employee?.manager?.name == authentication?.name")
Employee save(#Param("employee") Employee employee);
#Override
#PreAuthorize("#employeeRepository.findOne(#id)?.manager?.name == authentication?.name")
void delete(#Param("id") Long id);
#Override
#PreAuthorize("#employee?.manager?.name == authentication?.name")
void delete(#Param("employee") Employee employee);
}
So my question is how to send credential from authorized page using new javascript fetch API to interact with REST repositories without additional security configuration?
The root of the problem is that fetch() doesn't send cookies by default. So I should add credentials: 'include' to request options object:
fetch(`${root}/employees?size=${pageSize}`, {
method: 'GET',
credentials: 'include'})
references
Related
I'm trying to add basic authentication to my spring boot back end. What I have so far is an angular front end login page and some basic authentication set up. Right now it allows one user account with user:"user" and password:"password". I'd like to be able to have database to store user details in and everytime someone trys to login the backend can just look for those details in the database. My plan is to use DynamoDB how would I do this from the websecurityconfig class?
Backend
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user")
.password("password")
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login")
.permitAll().anyRequest()
.authenticated()
.and()
.httpBasic();
}
}
Controller
public class LoginController {
#RequestMapping(value ="/login", method = RequestMethod.POST, headers = { "Content-type=application/json",
"Access-Control-Allow-Origin=*" }, consumes = "application/json")
public boolean login(#RequestBody UserModel user) {
System.out.println(user.getUsername());
System.out.println(user.getPassword());
return user.getUsername().equals("user") && user.getPassword().equals("password");
}
#RequestMapping("/user")
public Principal user(HttpServletRequest request) {
String authToken = request.getHeader("Authorization")
.substring("Basic".length()).trim();
return () -> new String(Base64.getDecoder()
.decode(authToken)).split(":")[0];
}
}
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.
I've made a spring page using Spring Security. When I try to access any url inside this page, if the session is not set, it will redirect you to the login page: /login. This is fine, but now I've made a simple http rest api inside this web. What I want if I try to access any url inside /api/** just drop the 401, instead of sending a HTTP redirect to login.
I have made a Filter with preHandle:
public class BusinessKeyInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()
&&
// when Anonymous Authentication is enabled
!(auth instanceof AnonymousAuthenticationToken)) {
// other stuf ....
}
} else {
if (request.getRequestURI().startsWith("/api")) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return false;
}
}
return true;
}
}
But in this case request URI is already /login
My configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and().sessionManagement()
.invalidSessionUrl("/login?invalid")
.and().csrf().disable().formLogin()
.loginPage("/login")
.failureHandler(customAuthenticationFailureHandler)
.defaultSuccessUrl("/loggedIn")
.usernameParameter("email")
.passwordParameter("password")
.successHandler(authenticationSuccessHandler)
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling()
.accessDeniedPage("/access-denied")
;
}
I would recommend not mixing your previous security configuration with your new REST api config. You could do the following:
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Configuration
#Order(1)
public static class WebConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatchers("/web")
...
/* Your previous config would go here */
}
}
#Configuration
#Order(2)
public static class ApiConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatchers("/web")
... /* Your /api configuration goes here */
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
}
#Bean
AuthenticationEntryPoint customAuthenticationEntryPoint() {
return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
}
}
}
This way, you could configure your rest api separately. Now you can have different a authentication entry point for your rest api. The fact is that you're most likely going to want to also provide a custom failure handler and success handler, which you can now do easily, and which will remain separate from the rest of your web application.
So I have this project, which really all I want to do is be able to have a user log in and get access to a specific page:
Security
#Configuration
#EnableWebSecurity
public class MainSecurityConfig extends WebSecurityConfigurerAdapter {
#Resource
private UserDetailsServiceImpl userDetailsService;
#Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable();
http
.authorizeRequests()
.antMatchers("/", "/**", "/login/**", "/index.html", "/login.html", "/components/**", "/css/**", "/js/**", "/fonts/**", "/images/**", "/.sass-cache/**", "/services.html").permitAll()
.anyRequest().authenticated();
http.formLogin()
.loginPage("/login")
.failureForwardUrl("/login.html")
.usernameParameter("user")
.passwordParameter("password");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
When I sent the /login request from angularjs as a POST I was hitting the UserDetailsServiceImpl which is good, but the username was coming in empty.
UserDetailsServiceImpl
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
#Resource
private HttpSession httpSession;
#Resource
private UserDao userDao;
#Override
public UserDetails loadUserByUsername(String user) throws UsernameNotFoundException {
User userByEmail = userDao.findUserByEmail(user);
UserDetailsImpl userDetails = new UserDetailsImpl(userByEmail, httpSession.getId());
return userDetails;
}
}
So I did some googling and it said that the /login request has to be GET, which in itself confused me, should we really be plonking the username and password into the url? Or am I thinking about this wrong. Anyway, here's the angularJS code:
$scope.loginUser = function () {
$scope.user.user = $scope.email;
$scope.user.password = $scope.password;
$http.get("/login", { params: {username: $scope.user.user, password: $scope.user.password}});
I no longer hit the breakpoints now within UserDetailsServiceImpl and rather I am getting a 404.
UPDATE
After updating the processing url, I now post it but the username that get's passed server-side is empty
$scope.loginUser = function () {
$scope.user.username = $scope.email;
$scope.user.password = $scope.password;
$http.post("/api/authentication", $scope.user);
Everything up to here is fine, it's just when java handles it
If you are using Angular you have not a loginPage because you are writing a SPA and page navigation is managed by Angular itself.
You should use loginProcessingUrl that defines only the login submission url
.and()
.formLogin()
.loginProcessingUrl("/api/authentication")
.usernameParameter("username")
.passwordParameter("password")
To submit you login you need to do a POST not a GET. Probably links mean url to access a login page not to submit.
In the example above you have to do a POST using url /api/authentication with a body containing username and password
Also if i've seen you already found the solution, i've published a project based on Spring Boot 2.0 and angular 6 (angularjs is quite outdated) with spring security and a stateful authentication (the same you were searching for)
https://github.com/ValerioMC/vforge-stateful-auth
It's just a starting point.
The issue was with my AngularJS $http.post request, I solved it by adding headers for 'application/x-www-form-urlendcoded' as it is not the default header:
$http({
method: 'POST',
url: '/api/authentication',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: 'username=' + $scope.email + '&password=' + $scope.password
});
Hi to all Spring Experts!
I have an issue that I'm trying to solve for a while but i think that i have reached a dead end.
So basically what I need, is to configure my Spring-Security (in Spring-Boot) to have two authentication mechanisms (one for Legacy JSP pages and one for REST APIs). So I followed the following post:
multiple authentication mechanisms in a single app using java config
It worked fine with one LDAP authentication provider. But then I tried to extend my LDAP connection to also obtain a ticket from a third party service (that will be used for future connections to other services), and there I had a problem.
So I created a new Authentication Token, Filter and Authentication provider, but the default UsernamePasswordAuthenticationFilter is being fired first, no matter what I do.
I tried to follow this post How to configure a custom filter programatically in Spring Security? and saw that the problem might be in the fact that my filter was extending UsernamePasswordAuthenticationFilter. So I removed this and tried to have a simple AbstractAuthenticationProcessingFilter, still - no luck.
I think the problem is in my WebSecurity configuration. Currently, with the following code I'm gonna share, the REST Api authentication is returning 405 - method not allowed and the legacy Login is stuck in an infinite loop and crashes, even before I hit "Login".
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true) //Enables #PreAuthorize on methods
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private LDAPConfigurationBean ldapBean;
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//HERE GOES LDAP CONNECTION STUFF
// Add the custom LDAP + Token provider to the Authentication provider chain
auth.authenticationProvider(new TicketAndLDAPAuthenticationProvider(authenticator,authoritiesPopulator));
// Creating an LDAP provider using the authenticator and the populator.
auth.authenticationProvider(new LdapAuthenticationProvider(authenticator,authoritiesPopulator));
}
#Configuration
#Order(1)
public static class ConfigureFilters extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.addFilterBefore(new TicketAndLDAPAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class);
}
}
//Management Endpoints Authorization
#Configuration
#Order(2)
public static class EndpointsWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/manage/health")
.authorizeRequests()
.anyRequest().permitAll();
}
}
//API Authentication+Authorization
#Configuration
#Order(3)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Autowired
private RestAuthenticationEntryPoint authenticationEntryPoint;
#Autowired
private RestAuthSuccessHandler authSuccessHandler;
#Autowired
private RestAuthFailureHandler authFailureHandler;
#Autowired
private RestLogoutSuccessHandler logoutSuccessHandler;
private String LOGIN_PATH = "/api/authenticate";
private String USERNAME = "username";
private String PASSWORD = "password";
protected void configure(HttpSecurity http) throws Exception {
/*CSRF configuration*/
http.csrf().disable();
http
.antMatcher(LOGIN_PATH)
.authorizeRequests()
.anyRequest().permitAll();
http
.antMatcher("/api/**")
//Stateless session creation - no session will be created or used by Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.formLogin().permitAll()
.loginProcessingUrl(LOGIN_PATH)
.usernameParameter(USERNAME)
.passwordParameter(PASSWORD)
.successHandler(authSuccessHandler)
.failureHandler(authFailureHandler)
.and()
.logout().permitAll()
.logoutSuccessHandler(logoutSuccessHandler);
http
.authorizeRequests().anyRequest().authenticated();
}
}
//JSP Authentication+Authorization
#Configuration
#Order(4)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
/*CSRF configuration*/
http.csrf().disable();
/*Static content*/
http
.authorizeRequests()
.antMatchers("/css*//**").permitAll()
.antMatchers("/images*//**").permitAll()
.antMatchers("/scripts*//**").permitAll()
.antMatchers("/fonts*//**").permitAll()
.antMatchers("/login*").anonymous();
/*Login / Logout configuration*/
http
.formLogin()
.loginPage("/login.htm").permitAll()
.defaultSuccessUrl("/index.htm?name=******")
.failureUrl("/login.htm?error=true")
.and()
.logout().permitAll()
.logoutSuccessUrl("/login.htm")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
/*URL roles authorizations*/
http
.authorizeRequests().anyRequest().authenticated();
}
}
}
As you can see, I am trying to configure my filter in the "Configure Filters" method - but I have also tried to configure it inside the adapters, with / without a #Bean annotation - all with no luck.
Filter:
public class TicketAndLDAPAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public TicketAndLDAPAuthenticationFilter() {
super("/*");
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//Save the password for later
String username = request.getParameter("username");
String password = request.getParameter("password");
TicketAndLDAPAuthenticationToken token = new TicketAndLDAPAuthenticationToken(username,password,null);
return token;
}
}
Edit: forgot to add to the filter:
if ( request.getParameter( "username" ) == null || request.getParameter( "password" ) == null ) == null ) {
return null;
}
Now I get 405 in both login mechanisms.
Token:
public class TicketAndLDAPAuthenticationToken extends UsernamePasswordAuthenticationToken {
private AuthTicket otp;
private String restoredPassword;
public TicketAndLDAPAuthenticationToken( String username, String password, RestAuthLoginTicket otp ) {
super( username, password );
this.otp = otp;
}
public AuthTicket getOTP() {
return otp;
}
public AuthTicket getOtp() {
return otp;
}
public void setOtp(AuthTicket otp) {
this.otp = otp;
}
}
Provider:
public class TicketAndLDAPAuthenticationProvider extends LdapAuthenticationProvider {
#Autowired
TokenUtils tokenUtils;
public TicketAndLDAPAuthenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) {
super(authenticator, authoritiesPopulator);
}
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
TicketAndLDAPAuthenticationToken token = (TicketAndLDAPAuthenticationToken) super.authenticate(authentication);
token.setOtp(tokenUtils.getTicket(token));
return token;
}
#Override
public boolean supports(Class<?> authentication) {
return TicketAndLDAPAuthenticationToken.class.isAssignableFrom(authentication);
}
}
Thanks in advance!!
So I found the issue(s).
First of all, the right way to configure the authentication managers is not how I configured above because there is no antMatcher and this caused my resources and pages to be open to everybody.
Secondly, the problem that caused the infinite redirects and error 405 was that I haven't defined my filter to accept post.
After fixing that, my JSP login form and authentication mechanism worked fine, but the "/api" was redirecting to the login page instead of the resource.
What brings me to my final point - the http.formLogin() is creating a UsernamePasswordAuthenticationFilter. I have two of them - one for each login. So I had to add http.addFilterBefore() for each one of the logins, but with a different URL.
The "/api" url was again using the default redirects of Spring instead of what I have defined, so I had to override them.
These are the configurations and filters that are working for me:
Security Configuration:
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true) //Enables #PreAuthorize on methods
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private LDAPConfigurationBean ldapBean;
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//LDAP Stuff
TicketAndLDAPAuthenticationProvider ticketAndLDAPAuthenticationProvider = new TicketAndLDAPAuthenticationProvider(authenticator,authoritiesPopulator);
auth.authenticationProvider(ticketAndLDAPAuthenticationProvider);
LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(authenticator,authoritiesPopulator);
auth.authenticationProvider(ldapAuthenticationProvider);
}
//Management Endpoints Authorization
#Configuration
#Order(1)
public static class EndpointsWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/manage/health")
.authorizeRequests()
.anyRequest().permitAll();
}
}
//API Authentication+Authorization
#Configuration
#Order(2)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Autowired
private RestAuthenticationEntryPoint authenticationEntryPoint;
#Autowired
private RestAuthSuccessHandler authSuccessHandler;
#Autowired
private RestAuthFailureHandler authFailureHandler;
#Autowired
private RestLogoutSuccessHandler logoutSuccessHandler;
private String LOGIN_PATH = "/api/authenticate";
protected void configure(HttpSecurity http) throws Exception {
/*CSRF configuration*/
http.csrf().disable();
http.addFilterBefore(new TicketAndLDAPAuthenticationFilter(LOGIN_PATH,authSuccessHandler,authFailureHandler), UsernamePasswordAuthenticationFilter.class);
http
.antMatcher("/api/**")
// Stateless session creation - no session will be created or used by Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.logout().permitAll()
.logoutSuccessHandler(logoutSuccessHandler);
http
.authorizeRequests().anyRequest().authenticated();
}
}
//JSP Authentication+Authorization
#Configuration
#Order(3)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
private String LOGIN_PATH = "/login.htm";
#Override
protected void configure(HttpSecurity http) throws Exception {
/*CSRF configuration*/
http.csrf().disable();
http.addFilterBefore(new TicketAndLDAPAuthenticationFilter(LOGIN_PATH), UsernamePasswordAuthenticationFilter.class);
/*Static content*/
http
.authorizeRequests()
.antMatchers("/css*//**").permitAll()
.antMatchers("/images*//**").permitAll()
.antMatchers("/scripts*//**").permitAll()
.antMatchers("/fonts*//**").permitAll()
.antMatchers("/login*").anonymous();
/*Login / Logout configuration*/
http
.formLogin()
.loginPage(LOGIN_PATH).permitAll()
.defaultSuccessUrl("/index.htm?name=******")
.failureUrl("/login.htm?error=true")
.and()
.logout().permitAll()
.logoutSuccessUrl("/login.htm")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
/*URL roles authorizations*/
http
.authorizeRequests().anyRequest().authenticated();
}
}
}
And the Filter:
public class TicketAndLDAPAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public TicketAndLDAPAuthenticationFilter(String defaultProcessUrl) {
super(new AntPathRequestMatcher(defaultProcessUrl, "POST"));
}
public TicketAndLDAPAuthenticationFilter(String defaultProcessUrl, AuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationFailureHandler authenticationFailureHandler) {
super(new AntPathRequestMatcher(defaultProcessUrl, "POST"));
setAuthenticationFailureHandler(authenticationFailureHandler);
setAuthenticationSuccessHandler(authenticationSuccessHandler);
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//Save the password for later
String username = request.getParameter("username");
String password = request.getParameter("password");
if ( username==null || password==null) {
return null;
}
TicketAndLDAPAuthenticationToken token = new TicketAndLDAPAuthenticationToken(username,password,null);
return token;
}
}