From c61ba1deb4cf58bc44e1dfb272052dd64150eb49 Mon Sep 17 00:00:00 2001 From: Alexander Alexeev Date: Sat, 26 Nov 2016 13:19:17 +0700 Subject: working spring security config --- .../juick/api/configuration/ApiSecurityConfig.java | 35 +++++----------------- .../java/com/juick/api/tests/AuthSimpleTest.java | 8 +++++ juick-core/src/main/java/com/juick/User.java | 19 ++++++++++++ .../security/JuickAuthenticationProvider.java | 23 +++++++++----- .../juick/server/security/entities/JuickUser.java | 2 +- .../main/java/com/juick/service/UserService.java | 4 +++ .../java/com/juick/service/UserServiceImpl.java | 33 ++++++++++++++++++++ 7 files changed, 89 insertions(+), 35 deletions(-) create mode 100644 juick-api/src/test/java/com/juick/api/tests/AuthSimpleTest.java diff --git a/juick-api/src/main/java/com/juick/api/configuration/ApiSecurityConfig.java b/juick-api/src/main/java/com/juick/api/configuration/ApiSecurityConfig.java index 8d074f7c..d7904199 100644 --- a/juick-api/src/main/java/com/juick/api/configuration/ApiSecurityConfig.java +++ b/juick-api/src/main/java/com/juick/api/configuration/ApiSecurityConfig.java @@ -2,22 +2,16 @@ package com.juick.api.configuration; import com.juick.server.security.JuickAuthenticationEntryPoint; import com.juick.server.security.JuickAuthenticationProvider; -import com.juick.server.security.entities.JuickUser; import com.juick.service.UserService; -import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.http.HttpMethod; -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.config.http.SessionCreationPolicy; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; import javax.inject.Inject; @@ -40,32 +34,19 @@ public class ApiSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() - .antMatchers("/home").hasRole("USER") .antMatchers(HttpMethod.OPTIONS).permitAll() - .and().httpBasic().authenticationEntryPoint(getBasicAuthEntryPoint()) + .anyRequest().hasRole("USER") + .and().httpBasic().authenticationEntryPoint(getJuickAuthenticationEntryPoint()) + .and().anonymous() + .and().servletApi() .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and().exceptionHandling().authenticationEntryPoint(getBasicAuthEntryPoint()) - .and().authenticationProvider(new JuickAuthenticationProvider()); + .and().exceptionHandling().authenticationEntryPoint(getJuickAuthenticationEntryPoint()) + .and().authenticationProvider(new JuickAuthenticationProvider(userService)) + .headers().cacheControl(); } @Bean - public JuickAuthenticationEntryPoint getBasicAuthEntryPoint() { + public JuickAuthenticationEntryPoint getJuickAuthenticationEntryPoint() { return new JuickAuthenticationEntryPoint(); } - - @Bean("userDetailsService") - @Override - public UserDetailsService userDetailsServiceBean() throws Exception { - return username -> { - if (StringUtils.isBlank(username)) - throw new UsernameNotFoundException("Invalid user name " + username); - - com.juick.User user = userService.getUserByName(username); - - if (user != null) - return new JuickUser(user); - - throw new UsernameNotFoundException("The username " + username + " is not found"); - }; - } } diff --git a/juick-api/src/test/java/com/juick/api/tests/AuthSimpleTest.java b/juick-api/src/test/java/com/juick/api/tests/AuthSimpleTest.java new file mode 100644 index 00000000..d22d3cf7 --- /dev/null +++ b/juick-api/src/test/java/com/juick/api/tests/AuthSimpleTest.java @@ -0,0 +1,8 @@ +package com.juick.api.tests; + +/** + * Created by aalexeev on 11/26/16. + */ +public class AuthSimpleTest { + private final String HEADER = "Authorization: Basic dXNlcjE6dXNlcjFQYXNz"; // user1:user1Pass +} diff --git a/juick-core/src/main/java/com/juick/User.java b/juick-core/src/main/java/com/juick/User.java index 03805a65..364bc6ca 100644 --- a/juick-core/src/main/java/com/juick/User.java +++ b/juick-core/src/main/java/com/juick/User.java @@ -39,6 +39,7 @@ public class User { private String authHash; private boolean banned; private String credentials; + private String lang; public User() { } @@ -52,6 +53,7 @@ public class User { this.messagesCount = u.getUnreadCount(); this.authHash = u.getAuthHash(); this.banned = u.isBanned(); + this.credentials = u.getCredentials(); } @Override @@ -75,6 +77,7 @@ public class User { .append("fullName", fullName) .append("jid", jid) .append("messagesCount", messagesCount) + .append("lang", lang) .append("banned", banned) .toString(); } @@ -164,4 +167,20 @@ public class User { public void setCredentials(String credentials) { this.credentials = credentials; } + + public String getLang() { + return lang; + } + + public void setLang(String lang) { + this.lang = lang; + } + + public int getMessagesCount() { + return messagesCount; + } + + public void setMessagesCount(int messagesCount) { + this.messagesCount = messagesCount; + } } diff --git a/juick-server/src/main/java/com/juick/server/security/JuickAuthenticationProvider.java b/juick-server/src/main/java/com/juick/server/security/JuickAuthenticationProvider.java index 8d0bfddb..87908950 100644 --- a/juick-server/src/main/java/com/juick/server/security/JuickAuthenticationProvider.java +++ b/juick-server/src/main/java/com/juick/server/security/JuickAuthenticationProvider.java @@ -1,16 +1,18 @@ package com.juick.server.security; +import com.juick.User; import com.juick.server.security.entities.JuickUser; import com.juick.service.UserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.LockedException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; +import org.springframework.util.Assert; import javax.inject.Inject; -import java.util.Collections; /** * Created by vitalyster on 25.11.2016. @@ -18,20 +20,27 @@ import java.util.Collections; public class JuickAuthenticationProvider implements AuthenticationProvider { private final Logger logger = LoggerFactory.getLogger(getClass()); + private final UserService userService; + @Inject - private UserService userService; + public JuickAuthenticationProvider(UserService userService) { + Assert.notNull(userService); + this.userService = userService; + } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String name = authentication.getName(); String password = authentication.getCredentials().toString(); - boolean isAuthenticated = userService.checkPassword(name, password) > 0; - - logger.info("user {} authenticated: {}", name, isAuthenticated); + User user = userService.getFullyUserByName(name); + if (user != null) { + if (user.isBanned()) + throw new LockedException("Username \"" + name + "\" is banned"); - return isAuthenticated ? - new UsernamePasswordAuthenticationToken(name, password, JuickUser.USER_AUTHORITY) : null; + return new UsernamePasswordAuthenticationToken(name, password, JuickUser.USER_AUTHORITY); + } + return null; } @Override diff --git a/juick-server/src/main/java/com/juick/server/security/entities/JuickUser.java b/juick-server/src/main/java/com/juick/server/security/entities/JuickUser.java index fd06b65b..3e413bf6 100644 --- a/juick-server/src/main/java/com/juick/server/security/entities/JuickUser.java +++ b/juick-server/src/main/java/com/juick/server/security/entities/JuickUser.java @@ -43,7 +43,7 @@ public class JuickUser implements UserDetails { @Override public boolean isAccountNonLocked() { - return false; + return true; } @Override diff --git a/juick-server/src/main/java/com/juick/service/UserService.java b/juick-server/src/main/java/com/juick/service/UserService.java index cfd5092a..4d7d09c9 100644 --- a/juick-server/src/main/java/com/juick/service/UserService.java +++ b/juick-server/src/main/java/com/juick/service/UserService.java @@ -28,6 +28,10 @@ public interface UserService { User getUserByName(String username); + User getFullyUserByName(String username); + + List getFullyUsersByNames(Collection usernames); + User getUserByJID(String jid); List getUsersByName(Collection unames); 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 2bdc4d41..d1e4eff5 100644 --- a/juick-server/src/main/java/com/juick/service/UserServiceImpl.java +++ b/juick-server/src/main/java/com/juick/service/UserServiceImpl.java @@ -129,6 +129,39 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { return result; } + @Override + // No need marks with @Transactional annotation + public User getFullyUserByName(final String username) { + if (StringUtils.isNotBlank(username)) { + List list = getFullyUsersByNames(Collections.singletonList(username)); + if (!list.isEmpty()) + return list.get(0); + } + return null; + } + + @Transactional(readOnly = true) + @Override + public List getFullyUsersByNames(final Collection usernames) { + if (CollectionUtils.isEmpty(usernames)) + return Collections.emptyList(); + + return getNamedParameterJdbcTemplate().query( + "SELECT id, nick, passw, lang, banned FROM users WHERE nick in (:names)", + new MapSqlParameterSource("names", usernames), + (rs, rowNum) -> { + User user = new User(); + + user.setUid(rs.getInt(1)); + user.setName(rs.getString(2)); + user.setCredentials(rs.getString(3)); + user.setLang(rs.getString(4)); + user.setBanned(rs.getBoolean(5)); + + return user; + }); + } + @Transactional(readOnly = true) @Override public User getUserByJID(final String jid) { -- cgit v1.2.3