aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexander Alexeev2017-04-05 17:36:38 +0700
committerGravatar Vitaly Takmazov2017-04-05 14:02:56 +0300
commita9a2c587a4de11ce04aaae7a0c1a5dab1430794a (patch)
treebd86b40c1fefc10b3fa30d370ce0cdee5ba4ee06
parent4c99585f95cda1839f364524b6f68a16d063ed61 (diff)
login by hash, remember-me
-rw-r--r--juick-server/src/main/java/com/juick/server/security/HashParamAuthenticationFilter.java66
-rw-r--r--juick-server/src/main/java/com/juick/service/UserServiceImpl.java5
-rw-r--r--juick-www/src/main/java/com/juick/www/configuration/WebSecurityConfig.java41
-rw-r--r--juick-www/src/main/java/com/juick/www/controllers/Login.java40
4 files changed, 107 insertions, 45 deletions
diff --git a/juick-server/src/main/java/com/juick/server/security/HashParamAuthenticationFilter.java b/juick-server/src/main/java/com/juick/server/security/HashParamAuthenticationFilter.java
new file mode 100644
index 00000000..df1ae38c
--- /dev/null
+++ b/juick-server/src/main/java/com/juick/server/security/HashParamAuthenticationFilter.java
@@ -0,0 +1,66 @@
+package com.juick.server.security;
+
+import com.juick.User;
+import com.juick.server.security.entities.JuickUser;
+import com.juick.service.UserService;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.authentication.RememberMeAuthenticationToken;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Created by aalexeev on 4/5/17.
+ */
+public class HashParamAuthenticationFilter extends OncePerRequestFilter {
+ public static final String PARAM_NAME = "hash";
+
+ private final UserService userService;
+
+
+ public HashParamAuthenticationFilter(UserService userService) {
+ this.userService = userService;
+ }
+
+ @Override
+ protected void doFilterInternal(
+ HttpServletRequest request,
+ HttpServletResponse response,
+ FilterChain filterChain) throws ServletException, IOException {
+
+ String hash = request.getHeader(PARAM_NAME);
+
+ if (hash == null)
+ hash = request.getParameter(PARAM_NAME);
+
+ if (hash != null && authenticationIsRequired()) {
+ User user = userService.getUserByHash(hash);
+
+ if (!user.isAnonymous())
+ SecurityContextHolder.getContext().setAuthentication(
+ new RememberMeAuthenticationToken(hash, new JuickUser(user), JuickUser.USER_AUTHORITY));
+ }
+
+ filterChain.doFilter(request, response);
+ }
+
+ private boolean authenticationIsRequired() {
+ Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
+
+ if (existingAuth == null || !existingAuth.isAuthenticated())
+ return true;
+
+ if (existingAuth instanceof AnonymousAuthenticationToken)
+ return true;
+
+ return false;
+ }
+}
diff --git a/juick-server/src/main/java/com/juick/service/UserServiceImpl.java b/juick-server/src/main/java/com/juick/service/UserServiceImpl.java
index 81a1fea7..1b33a6d3 100644
--- a/juick-server/src/main/java/com/juick/service/UserServiceImpl.java
+++ b/juick-server/src/main/java/com/juick/service/UserServiceImpl.java
@@ -4,6 +4,7 @@ import com.juick.User;
import com.juick.server.helpers.Auth;
import com.juick.server.helpers.EmailOpts;
import com.juick.server.helpers.UserInfo;
+import com.juick.server.security.entities.AnonymousUser;
import com.juick.util.UserUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -126,7 +127,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
return list.get(0);
}
// TODO: @NonNullable ?
- return new User();
+ return AnonymousUser.INSTANCE;
}
@Override
@@ -284,7 +285,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
return user;
}
}
- return new User();
+ return AnonymousUser.INSTANCE;
}
@Transactional
diff --git a/juick-www/src/main/java/com/juick/www/configuration/WebSecurityConfig.java b/juick-www/src/main/java/com/juick/www/configuration/WebSecurityConfig.java
index 2b8dc292..3c674d0c 100644
--- a/juick-www/src/main/java/com/juick/www/configuration/WebSecurityConfig.java
+++ b/juick-www/src/main/java/com/juick/www/configuration/WebSecurityConfig.java
@@ -1,17 +1,20 @@
package com.juick.www.configuration;
+import com.juick.server.security.HashParamAuthenticationFilter;
import com.juick.server.security.entities.JuickUser;
import com.juick.service.UserService;
import com.juick.service.security.JuickUserDetailsService;
-import com.juick.service.security.deprecated.RequestParamHashRememberMeServices;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
+import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.web.authentication.RememberMeServices;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import javax.annotation.Resource;
@@ -33,8 +36,15 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
return new JuickUserDetailsService(userService);
}
+ @Bean("authenticationManager")
+ @Override
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ return super.authenticationManagerBean();
+ }
+
@Override
protected void configure(HttpSecurity http) throws Exception {
+ http.addFilterAfter(hashParamAuthenticationFilter(), BasicAuthenticationFilter.class);
http
.authorizeRequests()
.antMatchers("/settings", "/pm/**").authenticated()
@@ -44,7 +54,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.and()
.sessionManagement().invalidSessionUrl("/")
.and()
- .logout().invalidateHttpSession(true).logoutUrl("/logout").logoutSuccessUrl("/")
+ .logout().invalidateHttpSession(true).logoutUrl("/logout").logoutSuccessUrl("/login?logout")
.and()
.formLogin()
.loginPage("/login")
@@ -53,30 +63,37 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
- .failureUrl("/login-error")
+ .failureUrl("/login?error=1")
.and()
.rememberMe()
.tokenValiditySeconds(6 * 30 * 24 * 3600)
.alwaysRemember(true)
//.useSecureCookie(true) // TODO Enable if https is supports
- .rememberMeCookieDomain(webDomain)
+ .rememberMeCookieDomain(webDomain).key(rememberMeKey)
.userDetailsService(userDetailsServiceBean())
- .rememberMeServices(rememberMeServices())
- .key(rememberMeKey)
- .and().authenticationProvider(authenticationProvider())
+ .and()
+ .csrf().disable()
+ .authenticationProvider(authenticationProvider())
.headers().defaultsDisabled().cacheControl();
}
+
@Bean
- public DaoAuthenticationProvider authenticationProvider() {
+ public DaoAuthenticationProvider authenticationProvider() throws Exception {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
- authenticationProvider.setUserDetailsService(userDetailsService());
+ authenticationProvider.setUserDetailsService(userDetailsServiceBean());
return authenticationProvider;
}
@Bean
- public RememberMeServices rememberMeServices() throws Exception {
- return new RequestParamHashRememberMeServices(rememberMeKey, userService);
+ public HashParamAuthenticationFilter hashParamAuthenticationFilter() {
+ return new HashParamAuthenticationFilter(userService);
+ }
+
+ @Override
+ public void configure(WebSecurity web) throws Exception {
+ web.debug(false);
+ web.ignoring().antMatchers("/style.css*", "/scripts.js*");
}
}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/Login.java b/juick-www/src/main/java/com/juick/www/controllers/Login.java
index a83cbc16..8f9a993a 100644
--- a/juick-www/src/main/java/com/juick/www/controllers/Login.java
+++ b/juick-www/src/main/java/com/juick/www/controllers/Login.java
@@ -19,47 +19,25 @@ package com.juick.www.controllers;
import com.juick.service.UserService;
import com.juick.util.UserUtils;
-import com.juick.www.Utils;
-import com.juick.www.WebApp;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-import javax.inject.Inject;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
+import org.springframework.web.bind.annotation.GetMapping;
/**
- *
* @author Ugnich Anton
*/
@Controller
public class Login {
- @Inject
- UserService userService;
- @Inject
- WebApp webApp;
+ @Autowired
+ private UserService userService;
- @RequestMapping(value = "/login", method = RequestMethod.GET)
- protected String doGetLoginForm(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ @GetMapping("/login")
+ public String getloginForm() {
com.juick.User visitor = UserUtils.getCurrentUser();
- if (!visitor.isAnonymous()) {
+
+ if (!visitor.isAnonymous())
return "redirect:/";
- }
+
return "views/login";
}
- @RequestMapping(value="/logout", method = RequestMethod.GET)
- public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null){
- new SecurityContextLogoutHandler().logout(request, response, auth);
- }
- return "redirect:/login?logout";
- }
}