GitLab steht aufgrund wichtiger Wartungsarbeiten am Montag, den 8. März, zwischen 17:00 und 19:00 Uhr nicht zur Verfügung.

Commit 1f0aeed3 authored by Andreas Gärtner's avatar Andreas Gärtner

Added authentification filter, handler and tokenservice.

parent 20734e6b
package de.thm.arsnova.connector.auth;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import de.thm.arsnova.connector.persistence.domain.User;
public class AuthenticationFilter extends AbstractAuthenticationProcessingFilter {
@Autowired
private AuthenticationTokenService tokenService;
public AuthenticationFilter(String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
}
@Override
public void afterPropertiesSet() {
super.setAuthenticationManager(new AuthenticationManager() {
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
return authentication;
}
});
super.afterPropertiesSet();
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ADMIN");
User user = tokenService.findUserByToken(request);
Authentication auth = null;
if(user != null) {
auth = new UsernamePasswordAuthenticationToken(
user.getAuthToken(), user.getAuthToken(), authorities);
} else {
throw new AuthenticationException("TOKEN_ERROR") {
private static final long serialVersionUID = 1L;
};
}
return auth;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
Authentication auth;
if(tokenService.findUserByToken(httpRequest) != null) {
try {
auth = attemptAuthentication(httpRequest, httpResponse);
if(auth != null) successfulAuthentication(httpRequest, httpResponse, chain, auth);
return;
}
catch (AuthenticationException failed) {
unsuccessfulAuthentication(httpRequest, httpResponse, failed);
return;
}
}
chain.doFilter(httpRequest, httpResponse);
}
}
package de.thm.arsnova.connector.auth;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.bind.annotation.RequestMethod;
public class AuthenticationHandler {
@Autowired
private AuthenticationTokenService tokenService;
@Bean
public RequestMatcher ajaxRequestMatcher() {
return new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest");
}
@Bean
public AuthenticationSuccessHandler authSuccessHandler() {
return new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
SecurityContextHolder.getContext().setAuthentication(authentication);
tokenService.authenticateUser(authentication, response);
response.setStatus(HttpServletResponse.SC_OK);
}
};
}
@Bean
public SimpleUrlAuthenticationSuccessHandler tokenAuthSuccessHandler() {
return new SimpleUrlAuthenticationSuccessHandler() {
@Override
protected String determineTargetUrl(HttpServletRequest request,
HttpServletResponse response) {
String context = request.getContextPath();
String fullURL = request.getRequestURI();
String url = fullURL.substring(fullURL.indexOf(context)+context.length());
return url;
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
String url = determineTargetUrl(request, response);
request.getRequestDispatcher(url).forward(request, response);
}
};
}
@Bean
public AuthenticationFailureHandler authFailureHandler() {
return new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
};
}
@Bean
public AuthenticationEntryPoint tokenAuthenticationEntryPoint() {
return new AuthenticationEntryPoint() {
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response, AuthenticationException authException)
throws IOException, ServletException {
String method = request.getMethod();
if(!RequestMethod.OPTIONS.toString().equals(method)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
};
}
}
package de.thm.arsnova.connector.auth;
import java.io.IOException;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import de.thm.arsnova.connector.persistence.domain.User;
import de.thm.arsnova.connector.persistence.repository.UserRepository;
@Service
public class AuthenticationTokenService {
@Autowired
private UserRepository userRep;
public final String HEADER_SECURITY_TOKEN = "X-Auth-Token";
/** Authenticates an user and writes the authentication token to
* the response body.
*
* @param Authentication auth
* @param UserDetails ud
*/
@PostAuthorize("isAuthenticated()")
public void authenticateUser(Authentication auth, HttpServletResponse response) throws IOException {
UserDetails ud = (UserDetails) auth.getPrincipal();
JSONObject obj = new JSONObject();
obj.put(HEADER_SECURITY_TOKEN, createAndStoreToken(ud));
response.getWriter().write(obj.toString());
}
/** Gets HEADER_SECURITY_TOKEN header from requests and tries to find
* user associated with it.
*
* @param HttpServletRequest request
* @return User user
*/
public User findUserByToken(HttpServletRequest request) {
String token = request.getHeader(HEADER_SECURITY_TOKEN);
User user = null;
if(token != null) {
user = userRep.findByToken(token);
}
return user;
}
/** Generates an authentication token.
*
* @param ud UserDetails
* @return The authentication token string.
*/
private String generateToken(UserDetails ud) {
Date now = new Date();
Md5PasswordEncoder encoder = new Md5PasswordEncoder();
return encoder.encodePassword(
ud.getUsername() + now.toString() + String.valueOf(Math.random()),
null
);
}
/** Creates an authentication token from given UserDetails and
* saves it in userRep.
*
* @param ud UserDetails
* @return The authentication token string.
*/
private String createAndStoreToken(UserDetails ud) {
User user = userRep.findOne(ud.getUsername());
String token = generateToken(ud);
if(user == null) {
user = new User();
user.setUserId(ud.getUsername());
}
user.setAuthToken(token);
userRep.save(user);
return token;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment