diff options
author | 2019-03-16 23:56:27 +0300 | |
---|---|---|
committer | 2019-03-16 23:56:27 +0300 | |
commit | 06105f76dbfa3b65e63ed06f9c4d5107bd49ed88 (patch) | |
tree | 5702c01cec9688039d891f4a711878706101c1c5 /src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java | |
parent | 3ea4cd1942fa4e763034da11c5fa429407b67829 (diff) | |
parent | a49105285d0d7719d7f222a507af2d5ac5b4bdb1 (diff) |
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java')
-rw-r--r-- | src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java b/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java new file mode 100644 index 00000000..44d97207 --- /dev/null +++ b/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java @@ -0,0 +1,71 @@ +package com.juick.service.security; + +import com.juick.User; +import com.juick.server.SignatureManager; +import com.juick.service.UserService; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.annotation.Nonnull; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.Map; +import java.util.stream.Collectors; + +public class HTTPSignatureAuthenticationFilter extends OncePerRequestFilter { + + private final SignatureManager signatureManager; + private final UserService userService; + + + public HTTPSignatureAuthenticationFilter( + final SignatureManager signatureManager, + final UserService userService) { + this.signatureManager = signatureManager; + this.userService = userService; + } + @Override + protected void doFilterInternal(@Nonnull HttpServletRequest request, @Nonnull HttpServletResponse response, @Nonnull FilterChain filterChain) throws IOException, ServletException { + if (authenticationIsRequired()) { + Map<String, String> headers = Collections.list(request.getHeaderNames()) + .stream() + .collect(Collectors.toMap(String::toLowerCase, request::getHeader)); + if (StringUtils.isNotEmpty(headers.get("signature"))) { + User user = signatureManager.verifySignature(request.getMethod(), request.getRequestURI(), headers); + String userUri = user.getUri().toString(); + if (!user.isAnonymous() || userUri.length() > 0) { + if (userUri.length() == 0) { + User userWithPassword = userService.getUserByName(user.getName()); + userWithPassword.setAuthHash(userService.getHashByUID(userWithPassword.getUid())); + Authentication authentication = new UsernamePasswordAuthenticationToken(userWithPassword.getName(), userWithPassword.getCredentials()); + SecurityContextHolder.getContext().setAuthentication(authentication); + } else { + Authentication authentication = new AnonymousAuthenticationToken(userUri, user, Collections.singletonList(new SimpleGrantedAuthority("ROLE_ANONYMOUS"))); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + } + } + } + + filterChain.doFilter(request, response); + } + + private boolean authenticationIsRequired() { + Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication(); + + return existingAuth == null || + !existingAuth.isAuthenticated() || + existingAuth instanceof AnonymousAuthenticationToken; + } +} |