Spring RESTful Token Web Service Review - java

I have been going square trying to implement a new RESTful web service using Spring.IO. I've worked through perhaps 30 different online examples that suppose to provide this example but none of them worked 'out of the box'.
A further complication is that 95% of examples use XML configuration exclusively, which in my personal opinion is not as readable as a pure java configuration.
After a great many hours I have managed to cobble together something that 'works' but I would very much be interested in feedback as to my particular implementation. Specifically:
Assuming the client authorisation token is not compromised is my implementation secure.
I was unable to correctly AutoWire the AuthenticationTokenProcessingFilter class in WebSecurityConfig due to the constructor requiring an AuthenticationManager. If there is a way to do this that would help clean things up a little.
The main application class:
#ComponentScan({"webservice"})
#Configuration
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
The WebSecurityConfig class (AFAIK this does the majority of the job previously performed by the XML):
#Configuration
#EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
AuthenticationTokenProcessingFilter authenticationTokenProcessingFilter;
#Autowired
CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
#Override
protected void configure(HttpSecurity http) throws Exception {
authenticationTokenProcessingFilter =
new AuthenticationTokenProcessingFilter(authenticationManager());
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests().antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(authenticationTokenProcessingFilter, AnonymousAuthenticationFilter.class)
.httpBasic().authenticationEntryPoint(customAuthenticationEntryPoint);
}
}
The AuthenticationTokenProcessingFilter which performs the token authentication on client connect:
public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
AuthenticationManager authManager;
public AuthenticationTokenProcessingFilter(AuthenticationManager authManager) {
this.authManager = authManager;
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
#SuppressWarnings("unchecked")
Map<String, String[]> parms = request.getParameterMap();
if(parms.containsKey("authToken")) {
String token = parms.get("authToken")[0];
// Validate the token
User user = TokenUtils.getUserFromToken(token);
// If we managed to get a user we can finish the authentication
if (user!=null) {
//Add a default authority for all users
List<GrantedAuthority> grantedAuths = new ArrayList();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
// build an Authentication object with the user's info
AbstractAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(user, token, grantedAuths);
// set the authentication into the SecurityContext
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
// continue thru the filter chain
chain.doFilter(request, response);
}
}
The TokenUtils class used by AuthenticationTokenProcessingFilter:
public class TokenUtils {
/**
* Get an authorisation token for the provided userId
*
* #param userId
* #return
*/
public static String getToken(long userId) {
throw new UnsupportedOperationException("Not implemented yet!");
}
/**
* Attempt to get a user for the provided token
*
* #param token
* #return User if found, otherwise null
*/
public static User getUserFromToken(String token) {
throw new UnsupportedOperationException("Not implemented yet!");
}
}
The CustomAuthenticationEntryPoint, which returns a 403 if the user was not successfully authenticated:
#Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
#Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: Authentication token was either missing or invalid." );
}
}
An finally my web service entry points:
#RestController
public class EntryPoints {
#RequestMapping(value = "/login", method={RequestMethod.POST})
public LoginResponse login(#RequestParam(value="username", required=true) String username,
#RequestParam(value="password", required=true) String password) {
LoginRequest loginRequest = new LoginRequest(username, password);
//Authenticate the user using the provided credentials
//If succesfull return authentication token
//return new LoginResponse(token);
throw new UnsupportedOperationException("Not implemented yet!");
}
#RequestMapping(value = "/account", method={RequestMethod.POST})
public AccountResponse account(#RequestParam(value="accountId", required=true) long accountId) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//Return the request account information
throw new UnsupportedOperationException("Not implemented yet!");
}
}

Related

Vaadin 21 View Roles

I want to rewrite my Vaadin application to Vaadin 21.
With the Vaadin starter builder (https://vaadin.com/start) I created a simple app.
Currently my main struggle is to apply my simple CustomAuthenticationProvider to the Security manager to able to use the #RolesAllowed({ "user", "admin","USER"}) annotation.
Main problem that my AuthToken is generated somewhere else...
Its generate somewhere an empty Granted Authrities and ignore my custom AuthProvider code.
Question:
How to nicely handle role based access control?
Where I can use this annotation correctly:
#RolesAllowed({ "user", "admin","USER"})
public class ProfileView extends VerticalLayout {
Console after login:
UsernamePasswordAuthenticationToken [Principal=c.farkas, Credentials=[PROTECTED], Authenticated=false, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=DDE103F559B2F64B917753636B800564], Granted Authorities=[]]
xxx[USERcica, admin, USER]
??UsernamePasswordAuthenticationToken [Principal=c.farkas, Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[USERcica, admin, USER]]
SecurityConfiguration.java
#EnableWebSecurity
#Configuration
public class SecurityConfiguration extends VaadinWebSecurityConfigurerAdapter {
#Autowired
private RequestUtil requestUtil;
#Autowired
private VaadinDefaultRequestCache vaadinDefaultRequestCache;
#Autowired
private ViewAccessChecker viewAccessChecker;
#Autowired
CustomAuthenticationProvider customAuthenticationProvider;
public static final String LOGOUT_URL = "/";
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// super.configure(http);
http.csrf().ignoringRequestMatchers(requestUtil::isFrameworkInternalRequest);
// nor with endpoints
http.csrf().ignoringRequestMatchers(requestUtil::isEndpointRequest);
// Ensure automated requests to e.g. closing push channels, service
// workers,
// endpoints are not counted as valid targets to redirect user to on
// login
http.requestCache().requestCache(vaadinDefaultRequestCache);
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry urlRegistry = http
.authorizeRequests();
// Vaadin internal requests must always be allowed to allow public Flow
// pages
// and/or login page implemented using Flow.
urlRegistry.requestMatchers(requestUtil::isFrameworkInternalRequest).permitAll();
// Public endpoints are OK to access
urlRegistry.requestMatchers(requestUtil::isAnonymousEndpoint).permitAll();
// Public routes are OK to access
urlRegistry.requestMatchers(requestUtil::isAnonymousRoute).permitAll();
urlRegistry.requestMatchers(getDefaultHttpSecurityPermitMatcher()).permitAll();
// all other requests require authentication
urlRegistry.anyRequest().authenticated();
// Enable view access control
viewAccessChecker.enable();
setLoginView(http, LoginView.class, LOGOUT_URL);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Custom authentication provider - Order 1
auth.authenticationProvider(customAuthenticationProvider);
// Built-in authentication provider - Order 2
/* auth.inMemoryAuthentication().withUser("admin").password("{noop}admin#password")
// {noop} makes sure that the password encoder doesn't do anything
.roles("ADMIN") // Role of the user
.and().withUser("user").password("{noop}user#password").credentialsExpired(true).accountExpired(true)
.accountLocked(true).roles("USER");*/
}
#Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.ignoring().antMatchers("/images/*.png");
}
}
CustomAuthenticationProvider.java
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
System.out.println(authentication);
try {
// LdapContext ldapContext =
ActiveDirectory.getConnection(username, password);
List<GrantedAuthority> authorityList = new ArrayList<GrantedAuthority>();
authorityList.add(new SimpleGrantedAuthority("USER" + "cica"));
authorityList.add(new SimpleGrantedAuthority("admin"));
authorityList.add(new SimpleGrantedAuthority("USER"));
System.out.println("xxx"+authorityList.toString());
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
username, password, authorityList);
System.out.println("??" + usernamePasswordAuthenticationToken);
String id = VaadinSession.getCurrent() != null ? VaadinSession.getCurrent().getSession().getId() : "";
return usernamePasswordAuthenticationToken;
} catch (NamingException e) {
// e.printStackTrace();
// throw new CortexException("Authentication failed");
throw new BadCredentialsException("Authentication failed");
}
}
#Override
public boolean supports(Class<?> aClass) {
return aClass.equals(UsernamePasswordAuthenticationToken.class);
}
}
You must add the ROLE_ prefix to tell Spring Security that the GrantedAuthority is of type role.
authorityList.add(new SimpleGrantedAuthority("ROLE_USER" + "cica"));
authorityList.add(new SimpleGrantedAuthority("ROLE_admin"));
authorityList.add(new SimpleGrantedAuthority("ROLE_USER"));

Spring Security responds empty body with empty basic auth credentials

I'm trying to make a basic authentication service, for some business logic i need to acceept all basic auth credentials and make them hit another service (and there it will be fail if the credentials are wrong).
So I'm trying to throw an exception when the basic auth is not present, or are empty credentials.
This is my SecurityConfigurer:
#Configuration
#EnableWebSecurity
public class SecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Autowired
STGAuthenticationProvider authProvider;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests().anyRequest().authenticated()
.and().httpBasic();
}
}
And this is my CustomAuthProvider:
#Component
public class STGAuthenticationProvider implements AuthenticationProvider {
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
if(!StringUtils.isBlank(username) && !StringUtils.isBlank(password)) {
return new UsernamePasswordAuthenticationToken(username, password, new ArrayList<>());
} else {
throw new STGNoCredentialsException(Constants.Error.NO_CREDENTIALS);
}
}
#Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
Actually my app gives me "401 Unauthorized" if i send a request with no auth (I would really like to get my custom Exception you can see at my CustomAuthProvider).
And when i send just 1 credential (username or password), or no one, my service answer me with empty body at POSTMAN. Can you guys help me?
From what I understand, your issue is similar to one I had a few days ago: I needed to return a 401 instead of a 403 whenever an endpoint was called with no authorisation or with auth token expired.
With respect to your code, I would add .exceptionHandling().authenticationEntryPoint(...) to your WebSecurityConfigurerAdapter as follows
#Configuration
#EnableWebSecurity
public class SecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
/* other stuff */
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests().anyRequest().authenticated()
.and().httpBasic()
.exceptionHandling().authenticationEntryPoint(/*custom exception*/);
}
}
and then, instead of /*custom exception*/ add something as new MyAuthException(), where MyAuthException looks like the following:
#Component
public class MyAuthException implements AuthenticationEntryPoint {
#Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) /*throws ...*/ {
response.setStatus(/* your status */);
response.getWriter().write(/*the body of your answer*/);
/* whatever else you want to add to your response */
/* or you could throw an exception, I guess*/
}
}
(I don't remember and right now I can't check whether this class needs to be marked as #Component, I think not).

Spring security. Cannot permit request in custom fiter

I need to implement authorization with a specific header (say "sessionId") and secure all uri's except one.
I extended OncePerRequestFilter and implemented custom AuthenticationProvider to check if sessionId is valid (as well as custom Token class etc).
How it works now: for any uri it immediately jumps to AuthSessionAuthenticationProvider's authenticate method right after AuthSessionFilter is applied and returns 403 if header sessionId isn't specified. But I want some uri's to allow access without that header.
It all together:
config:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers(permittedUris).permitAll()
.anyRequest().authenticated()
.and().exceptionHandling().accessDeniedHandler(new AuthSessionAccessDeniedHandler())
.and().addFilterBefore(new AuthSessionFilter(), BasicAuthenticationFilter.class);
}
Filter:
public class AuthSessionFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
Authentication auth = new AuthSessionToken(request.getHeader("sessionId"));
SecurityContextHolder.getContext().setAuthentication(auth);
filterChain.doFilter(request, response);
}
}
Provider:
public class AuthSessionAuthenticationProvider implements AuthenticationProvider {
//...
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
AuthSessionToken token = (AuthSessionToken) authentication;
if (token.getSessionId() == null) {
throw new AccessDeniedException("Missing header sessionId");
}
AuthSessionAuthorities user = authSessionService.getUserAuthoritiesToken(token.getSessionId());
if (user == null) {
throw new AccessDeniedException("Session ID invalid: " + token.getSessionId());
}
token.setAuthenticatedUser(user);
return token;
}
//...
}
I found more elegant solution that was developed exactly for that purpose.
It's a RequestHeaderAuthenticationFilter. And then antMatchers works as expected. The initial configuration looks like this:
#Bean
#SneakyThrows
public RequestHeaderAuthenticationFilter preAuthenticationFilter() {
RequestHeaderAuthenticationFilter preAuthenticationFilter = new RequestHeaderAuthenticationFilter();
preAuthenticationFilter.setPrincipalRequestHeader(SESSION_ID);
preAuthenticationFilter.setCredentialsRequestHeader(SESSION_ID);
preAuthenticationFilter.setExceptionIfHeaderMissing(false);
preAuthenticationFilter.setContinueFilterChainOnUnsuccessfulAuthentication(true);
preAuthenticationFilter.setAuthenticationManager(authenticationManager());
return preAuthenticationFilter;
}

Understanding jwt and login logic

I am new to jwt and im using some resources from the net to help me get to understand jwt properly , I am able now to generate a token and access a resource that requires authorisation, first , i have a controller like
#RequestMapping("/token")
public class TokenController {
private JwtGenerator jwtGenerator;
public TokenController(JwtGenerator jwtGenerator) {
this.jwtGenerator = jwtGenerator;
}
#PostMapping
public String generate(#RequestBody final JwtUser jwtUser) {
return jwtGenerator.generate(jwtUser);
}
excuse me for i will be posting a lot of code.I am using postman for testing
so when i pass this as a post
{
"useNe" : "ter",
"paord":"123",
"role":"ain"
} or
{
"username" : "ter",
"is":"123",
"role":"admin"
}
I am generating a token ,it should require a username and password i think before a jwt token should be produced and i want to implement a proper login ,below is the security config and other classes that i have
#EnableWebSecurity
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private JwtAuthenticationProvider authenticationProvider;
#Autowired
private JwtAuthenticationEntryPoint entryPoint;
#Bean
public AuthenticationManager authenticationManagerBean() {
return new ProviderManager(Collections.singletonList(authenticationProvider));
}
#Bean
public JwtAuthenticationTokenFilter authenticationTokenFilter() throws Exception {
JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
filter.setAuthenticationManager(authenticationManager());
// we set success handler so that we overide the default redirection
filter.setAuthenticationSuccessHandler(new JwtSuccessHandler());
return filter;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("**/rest/**").authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(entryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.headers().cacheControl();
}
}
how can i create a login that will generate a token , or is that not the standard for jwt , also i want to have two types of role user and admin, admin can access all resources while user can access some , here are other classes
public class JwtAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {
public JwtAuthenticationTokenFilter() {
super("/rest/**");
}
#Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse)
throws AuthenticationException, IOException, ServletException {
String header = httpServletRequest.getHeader("Authorisation");
if (header == null || !header.startsWith("Token")) {
throw new RuntimeException("JWT Token is missing");
}
String authenticationToken = header.substring(6);
JwtAuthenticationToken token = new JwtAuthenticationToken(authenticationToken);
return getAuthenticationManager().authenticate(token);
}
#Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
chain.doFilter(request, response);
}
}
And my jwt generator should this not require a an username and password for login
#Component
public class JwtGenerator {
public String generate(JwtUser jwtUser) {
Claims claims = Jwts.claims()
.setSubject(jwtUser.getUserName());
claims.put("userId", String.valueOf(jwtUser.getId()));
claims.put("role", jwtUser.getRole());
return Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS512, "youtube")
.compact();
}
}
#Component
public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
#Autowired
private JwtValidator validator;
#Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken)
throws AuthenticationException {
}
#Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken)
throws AuthenticationException {
JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) usernamePasswordAuthenticationToken;
String token = jwtAuthenticationToken.getToken();
JwtUser jwtUser = validator.validate(token);
if(jwtUser == null){
throw new RuntimeException("user token is incorrect" );
}
List<GrantedAuthority> grantedAuthorities = AuthorityUtils
.commaSeparatedStringToAuthorityList(jwtUser.getRole());
//we return an authenticated user
return new JwtUserDetails(jwtUser.getUserName(),jwtUser.getId(),token , grantedAuthorities);
}
#Override
public boolean supports(Class<?> aClass) {
return (JwtAuthenticationToken.class.isAssignableFrom(aClass));
}
}
How do i go about improving on this and end up with a proper login that generates a jwt and keeps it in headers for every request

Spring Security Token based Authentication

I have a rest api where I am authenticating using spring security Basic Authorization where client sends username and password for each request.
Now, I wanted to implement token based authentication where I will send a token in response header when user is authenticated at first. For further requests, client can include that token in the header which will be used to authenticate the user to the resources. I have two authentication providers tokenAuthenticationProvider and daoAuthenticationProvider
#Component
public class TokenAuthenticationProvider implements AuthenticationProvider {
#Autowired
private TokenAuthentcationService service;
#Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
final HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
final String token = request.getHeader(Constants.AUTH_HEADER_NAME);
final Token tokenObj = this.service.getToken(token);
final AuthenticationToken authToken = new AuthenticationToken(tokenObj);
return authToken;
}
#Override
public boolean supports(final Class<?> authentication) {
return AuthenticationToken.class.isAssignableFrom(authentication);
}
}
And in daoAuthenticationProvider I am setting custom userDetailsService and authenticating against user login details by fetching it from the database (which is working fine as long as user name and password are passed using Authorization:Basic bGllQXBpVXNlcjogN21wXidMQjRdTURtR04pag== as header)
But when I include token in the header using X-AUTH-TOKEN (which is Constants.AUTH_HEADER_NAME), tokenAuthenticationProvider is not being called. I am getting error as
{"timestamp":1487626368308,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/find"}
And here is how I am adding authentication providers.
#Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception {
final UsernamePasswordAuthenticationProvider daoProvider = new
UsernamePasswordAuthenticationProvider(this.service, this.passwordEncoder());
auth.authenticationProvider(this.tokenAuthenticationProvider);
auth.authenticationProvider(daoProvider);
}
Please suggest how can I implement Token based authentication without hurting the current behavior of spring security.
Here is how I was able to implement token based authentication and basic authentication
SpringSecurityConfig.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(this.participantService).passwordEncoder(this.passwordEncoder());
}
#Override
protected void configure(final HttpSecurity http) throws Exception
{
//Implementing Token based authentication in this filter
final TokenAuthenticationFilter tokenFilter = new TokenAuthenticationFilter();
http.addFilterBefore(tokenFilter, BasicAuthenticationFilter.class);
//Creating token when basic authentication is successful and the same token can be used to authenticate for further requests
final CustomBasicAuthenticationFilter customBasicAuthFilter = new CustomBasicAuthenticationFilter(this.authenticationManager() );
http.addFilter(customBasicAuthFilter);
}
}
TokenAuthenticationFilter.java
public class TokenAuthenticationFilter extends GenericFilterBean
{
#Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException
{
final HttpServletRequest httpRequest = (HttpServletRequest)request;
//extract token from header
final String accessToken = httpRequest.getHeader("header-name");
if (null != accessToken) {
//get and check whether token is valid ( from DB or file wherever you are storing the token)
//Populate SecurityContextHolder by fetching relevant information using token
final User user = new User(
"username",
"password",
true,
true,
true,
true,
authorities);
final UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(request, response);
}
}
CustomBasicAuthenticationFilter.java
#Component
public class CustomBasicAuthenticationFilter extends BasicAuthenticationFilter {
#Autowired
public CustomBasicAuthenticationFilter(final AuthenticationManager authenticationManager) {
super(authenticationManager);
}
#Override
protected void onSuccessfulAuthentication(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response, final Authentication authResult) {
//Generate Token
//Save the token for the logged in user
//send token in the response
response.setHeader("header-name" , "token");
}
}
As our CustomBasicAuthenticationFilter has been configured and added as a filter to the spring security,
Whenever basic authentication is successful the request will be redirected to onSuccessfulAuthentication where we set the token and send it in the response with some header "header-name".
If "header-name" is sent for further request, then the request will go through TokenAuthenticationFilter first before attempting to try Basic Authentication.
You can try setting your custom AuthenticationToken token in your authentication filter, for example:
public class AuthenticationFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
final String authTokenHeader = ((HttpServletRequest)request).getHeader(Constants.AUTH_HEADER_NAME);
if (authTokenHeader != null) {
SecurityContextHolder.getContext().setAuthentication(createAuthenticationToken(authTokenHeader));
}
chain.doFilter( request, response );
}
}

Categories