From 2f8988ad4ffce9a58bfa919dcded9921127bbaa0 Mon Sep 17 00:00:00 2001 From: svlada Date: Thu, 18 Aug 2016 16:37:18 +0200 Subject: [PATCH] Code refactoring and cleanup. --- pom.xml | 1 - src/main/java/com/svlada/entity/Role.java | 7 ++- src/main/java/com/svlada/entity/User.java | 22 ++++---- src/main/java/com/svlada/entity/UserRole.java | 52 +++++++++++++++++++ .../java/com/svlada/security/UserService.java | 7 +-- .../auth/RefreshTokenRequestMatcher.java | 24 --------- .../auth/ajax/AjaxAuthenticationProvider.java | 33 ++++++++++-- .../auth/jwt/BloomFilterTokenVerifier.java | 3 ++ .../auth/jwt/JwtAuthenticationProvider.java | 19 +++++-- ...wtTokenAuthenticationProcessingFilter.java | 4 +- .../security/config/WebSecurityConfig.java | 11 ++-- .../endpoint/RefreshTokenEndpoint.java | 31 +++++++++-- .../security/model/JwtTokenFactory.java | 45 ++++++++-------- .../com/svlada/security/model/Scopes.java | 16 ++++++ .../svlada/security/model/UserContext.java | 10 +++- .../com/svlada/security/model/UserRole.java | 16 ------ .../user/repository/UserRepository.java | 7 ++- .../user/service/DatabaseUserService.java | 27 +++------- src/main/resources/application.yml | 3 +- src/main/resources/data.sql | 4 +- 20 files changed, 220 insertions(+), 122 deletions(-) create mode 100644 src/main/java/com/svlada/entity/UserRole.java delete mode 100644 src/main/java/com/svlada/security/auth/RefreshTokenRequestMatcher.java create mode 100644 src/main/java/com/svlada/security/model/Scopes.java delete mode 100644 src/main/java/com/svlada/security/model/UserRole.java diff --git a/pom.xml b/pom.xml index 3e3e2e9..18f703b 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,6 @@ com.h2database h2 - runtime diff --git a/src/main/java/com/svlada/entity/Role.java b/src/main/java/com/svlada/entity/Role.java index ca479cd..ce817a3 100644 --- a/src/main/java/com/svlada/entity/Role.java +++ b/src/main/java/com/svlada/entity/Role.java @@ -2,10 +2,15 @@ package com.svlada.entity; /** * Enumerated {@link User} roles. + * * @author vladimir.stankovic * * Aug 16, 2016 */ public enum Role { - ADMIN, PREMIUM_MEMBER, MEMBER + ADMIN, PREMIUM_MEMBER, MEMBER; + + public String authority() { + return "ROLE_" + this.name(); + } } diff --git a/src/main/java/com/svlada/entity/User.java b/src/main/java/com/svlada/entity/User.java index 7cd0dbc..df5336b 100644 --- a/src/main/java/com/svlada/entity/User.java +++ b/src/main/java/com/svlada/entity/User.java @@ -1,12 +1,14 @@ package com.svlada.entity; +import java.util.List; + import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @@ -22,15 +24,17 @@ public class User { @Column(name="password") private String password; - @Column(name="role") - @Enumerated(EnumType.STRING) - private Role role; + @OneToMany + @JoinColumn(name="APP_USER_ID", referencedColumnName="ID") + private List roles; - public User(Long id, String username, String password, Role role) { + public User() { } + + public User(Long id, String username, String password, List roles) { this.id = id; this.username = username; this.password = password; - this.role = role; + this.roles = roles; } public Long getId() { @@ -45,7 +49,7 @@ public class User { return password; } - public Role getRole() { - return role; + public List getRoles() { + return roles; } } diff --git a/src/main/java/com/svlada/entity/UserRole.java b/src/main/java/com/svlada/entity/UserRole.java new file mode 100644 index 0000000..3e9448f --- /dev/null +++ b/src/main/java/com/svlada/entity/UserRole.java @@ -0,0 +1,52 @@ +package com.svlada.entity; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Table; + +/** + * UserRole + * + * @author vladimir.stankovic + * + * Aug 18, 2016 + */ +@Entity +@Table(name = "USER_ROLE") +public class UserRole { + @Embeddable + public static class Id implements Serializable { + private static final long serialVersionUID = 1322120000551624359L; + + @Column(name = "APP_USER_ID") + protected Long userId; + + @Enumerated(EnumType.STRING) + @Column(name = "ROLE") + protected Role role; + + public Id() { } + + public Id(Long userId, Role role) { + this.userId = userId; + this.role = role; + } + } + + @EmbeddedId + Id id = new Id(); + + @Enumerated(EnumType.STRING) + @Column(name = "ROLE", insertable=false, updatable=false) + protected Role role; + + public Role getRole() { + return role; + } +} diff --git a/src/main/java/com/svlada/security/UserService.java b/src/main/java/com/svlada/security/UserService.java index 2aa78b2..3a40d13 100644 --- a/src/main/java/com/svlada/security/UserService.java +++ b/src/main/java/com/svlada/security/UserService.java @@ -1,6 +1,8 @@ package com.svlada.security; -import com.svlada.security.model.UserContext; +import java.util.Optional; + +import com.svlada.entity.User; /** * @@ -9,6 +11,5 @@ import com.svlada.security.model.UserContext; * Aug 17, 2016 */ public interface UserService { - public UserContext getByUsername(String username); - public UserContext getByUsernameAndPassword(String username, String password); + public Optional getByUsername(String username); } diff --git a/src/main/java/com/svlada/security/auth/RefreshTokenRequestMatcher.java b/src/main/java/com/svlada/security/auth/RefreshTokenRequestMatcher.java deleted file mode 100644 index c0d1291..0000000 --- a/src/main/java/com/svlada/security/auth/RefreshTokenRequestMatcher.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.svlada.security.auth; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; - -import com.svlada.security.config.WebSecurityConfig; - -/** - * Skip processing of Refresh token URL endpoint. - * - * @author vladimir.stankovic - * - * Aug 17, 2016 - */ -public class RefreshTokenRequestMatcher implements RequestMatcher { - private AntPathRequestMatcher matcher = new AntPathRequestMatcher(WebSecurityConfig.TOKEN_REFRESH_ENTRY_POINT); - - @Override - public boolean matches(HttpServletRequest request) { - return matcher.matches(request) ? false : true; - } -} diff --git a/src/main/java/com/svlada/security/auth/ajax/AjaxAuthenticationProvider.java b/src/main/java/com/svlada/security/auth/ajax/AjaxAuthenticationProvider.java index be1b3fc..eff8897 100644 --- a/src/main/java/com/svlada/security/auth/ajax/AjaxAuthenticationProvider.java +++ b/src/main/java/com/svlada/security/auth/ajax/AjaxAuthenticationProvider.java @@ -1,13 +1,23 @@ package com.svlada.security.auth.ajax; +import java.util.List; +import java.util.stream.Collectors; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.util.Assert; +import com.svlada.entity.User; import com.svlada.security.model.UserContext; import com.svlada.user.service.DatabaseUserService; @@ -19,23 +29,36 @@ import com.svlada.user.service.DatabaseUserService; */ @Component public class AjaxAuthenticationProvider implements AuthenticationProvider { - + private final BCryptPasswordEncoder encoder; private final DatabaseUserService userService; - + @Autowired - public AjaxAuthenticationProvider(final DatabaseUserService userService) { + public AjaxAuthenticationProvider(final DatabaseUserService userService, final BCryptPasswordEncoder encoder) { this.userService = userService; + this.encoder = encoder; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { - Assert.notNull(authentication, "No authentication data provided."); + Assert.notNull(authentication, "No authentication data provided"); String username = (String) authentication.getPrincipal(); String password = (String) authentication.getCredentials(); - UserContext userContext = userService.getByUsernameAndPassword(username, password); + User user = userService.getByUsername(username).orElseThrow(() -> new UsernameNotFoundException("User not found: " + username)); + + if (!encoder.matches(password, user.getPassword())) { + throw new BadCredentialsException("Authentication Failed. Username or Password not valid."); + } + if (user.getRoles() == null) throw new InsufficientAuthenticationException("User has no roles assigned"); + + List authorities = user.getRoles().stream() + .map(authority -> new SimpleGrantedAuthority(authority.getRole().authority())) + .collect(Collectors.toList()); + + UserContext userContext = UserContext.create(user.getUsername(), authorities); + return new UsernamePasswordAuthenticationToken(userContext, null, userContext.getAuthorities()); } diff --git a/src/main/java/com/svlada/security/auth/jwt/BloomFilterTokenVerifier.java b/src/main/java/com/svlada/security/auth/jwt/BloomFilterTokenVerifier.java index 0e58136..3f5e4be 100644 --- a/src/main/java/com/svlada/security/auth/jwt/BloomFilterTokenVerifier.java +++ b/src/main/java/com/svlada/security/auth/jwt/BloomFilterTokenVerifier.java @@ -1,5 +1,7 @@ package com.svlada.security.auth.jwt; +import org.springframework.stereotype.Component; + /** * BloomFilterTokenVerifier * @@ -7,6 +9,7 @@ package com.svlada.security.auth.jwt; * * Aug 17, 2016 */ +@Component public class BloomFilterTokenVerifier implements TokenVerifier { @Override public boolean verify(String jti) { diff --git a/src/main/java/com/svlada/security/auth/jwt/JwtAuthenticationProvider.java b/src/main/java/com/svlada/security/auth/jwt/JwtAuthenticationProvider.java index 4b216c6..6c8f21a 100644 --- a/src/main/java/com/svlada/security/auth/jwt/JwtAuthenticationProvider.java +++ b/src/main/java/com/svlada/security/auth/jwt/JwtAuthenticationProvider.java @@ -1,12 +1,16 @@ package com.svlada.security.auth.jwt; +import java.util.List; +import java.util.stream.Collectors; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Component; -import com.svlada.security.UserService; import com.svlada.security.auth.JwtAuthenticationToken; import com.svlada.security.config.JwtSettings; import com.svlada.security.model.JwtToken; @@ -25,13 +29,12 @@ import io.jsonwebtoken.Jws; * Aug 5, 2016 */ @Component +@SuppressWarnings("unchecked") public class JwtAuthenticationProvider implements AuthenticationProvider { - private final UserService userService; private final JwtSettings jwtSettings; @Autowired - public JwtAuthenticationProvider(UserService userService, JwtSettings jwtSettings) { - this.userService = userService; + public JwtAuthenticationProvider(JwtSettings jwtSettings) { this.jwtSettings = jwtSettings; } @@ -42,7 +45,13 @@ public class JwtAuthenticationProvider implements AuthenticationProvider { Jws jwsClaims = unsafeToken.parseClaims(jwtSettings.getTokenSigningKey()); String subject = jwsClaims.getBody().getSubject(); - UserContext context = userService.getByUsername(subject); + List scopes = jwsClaims.getBody().get("scopes", List.class); + + List authorities = scopes.stream() + .map(authority -> new SimpleGrantedAuthority(authority)) + .collect(Collectors.toList()); + + UserContext context = UserContext.create(subject, authorities); return new JwtAuthenticationToken(context, context.getAuthorities()); } diff --git a/src/main/java/com/svlada/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java b/src/main/java/com/svlada/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java index 45b3807..edd2f38 100644 --- a/src/main/java/com/svlada/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java +++ b/src/main/java/com/svlada/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java @@ -38,8 +38,8 @@ public class JwtTokenAuthenticationProcessingFilter extends AbstractAuthenticati public JwtTokenAuthenticationProcessingFilter(AuthenticationFailureHandler failureHandler, JwtTokenFactory tokenFactory, TokenExtractor tokenExtractor, - RequestMatcher requestMatcher) { - super(requestMatcher); + String filterProcessingUrl) { + super(filterProcessingUrl); this.failureHandler = failureHandler; this.tokenExtractor = tokenExtractor; this.tokenFactory = tokenFactory; diff --git a/src/main/java/com/svlada/security/config/WebSecurityConfig.java b/src/main/java/com/svlada/security/config/WebSecurityConfig.java index f0f6dba..dfee99c 100644 --- a/src/main/java/com/svlada/security/config/WebSecurityConfig.java +++ b/src/main/java/com/svlada/security/config/WebSecurityConfig.java @@ -16,7 +16,6 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic import com.fasterxml.jackson.databind.ObjectMapper; import com.svlada.security.RestAuthenticationEntryPoint; -import com.svlada.security.auth.RefreshTokenRequestMatcher; import com.svlada.security.auth.ajax.AjaxAuthenticationProvider; import com.svlada.security.auth.ajax.AjaxLoginProcessingFilter; import com.svlada.security.auth.jwt.JwtAuthenticationProvider; @@ -61,7 +60,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Bean protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter() throws Exception { - JwtTokenAuthenticationProcessingFilter filter = new JwtTokenAuthenticationProcessingFilter(failureHandler, tokenFactory, tokenExtractor, new RefreshTokenRequestMatcher()); + JwtTokenAuthenticationProcessingFilter filter = new JwtTokenAuthenticationProcessingFilter(failureHandler, tokenFactory, tokenExtractor, TOKEN_BASED_AUTH_ENTRY_POINT); filter.setAuthenticationManager(this.authenticationManager); return filter; } @@ -95,8 +94,12 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { .and() .authorizeRequests() - .antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point - .antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point + .antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point + .antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point + .antMatchers("/console").permitAll() // H2 Console Dash-board - only for testing + .and() + .authorizeRequests() + .antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() // Protected API End-points .and() .addFilterBefore(buildAjaxLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class); diff --git a/src/main/java/com/svlada/security/endpoint/RefreshTokenEndpoint.java b/src/main/java/com/svlada/security/endpoint/RefreshTokenEndpoint.java index b104e95..983c04c 100644 --- a/src/main/java/com/svlada/security/endpoint/RefreshTokenEndpoint.java +++ b/src/main/java/com/svlada/security/endpoint/RefreshTokenEndpoint.java @@ -1,6 +1,8 @@ package com.svlada.security.endpoint; import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -8,11 +10,16 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; +import org.springframework.security.authentication.InsufficientAuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import com.svlada.entity.User; import com.svlada.security.UserService; import com.svlada.security.auth.jwt.TokenVerifier; import com.svlada.security.config.JwtSettings; @@ -20,6 +27,7 @@ import com.svlada.security.config.WebSecurityConfig; import com.svlada.security.exceptions.InvalidJwtToken; import com.svlada.security.model.JwtToken; import com.svlada.security.model.JwtTokenFactory; +import com.svlada.security.model.Scopes; import com.svlada.security.model.UnsafeJwtToken; import com.svlada.security.model.UserContext; @@ -33,6 +41,7 @@ import io.jsonwebtoken.Jws; * * Aug 17, 2016 */ +@SuppressWarnings("unchecked") @RestController public class RefreshTokenEndpoint { @Autowired private JwtTokenFactory tokenFactory; @@ -43,17 +52,29 @@ public class RefreshTokenEndpoint { @RequestMapping(value="/api/auth/token", method=RequestMethod.GET, produces={ MediaType.APPLICATION_JSON_VALUE }) public @ResponseBody JwtToken refreshToken(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { UnsafeJwtToken unsafeToken = this.tokenFactory.createUnsafeToken(request.getHeader(WebSecurityConfig.JWT_TOKEN_HEADER_PARAM)); - Jws jwsClaims = unsafeToken.parseClaims(jwtSettings.getTokenSigningKey()); - - String subject = jwsClaims.getBody().getSubject(); - String jti = jwsClaims.getBody().getId(); + List scopes = jwsClaims.getBody().get("scopes", List.class); + if (scopes == null || scopes.isEmpty() + || !scopes.stream().filter(scope -> Scopes.REFRESH_TOKEN.authority().equals(scope)).findFirst().isPresent()) { + throw new InvalidJwtToken(); + } + + String jti = jwsClaims.getBody().getId(); if (!tokenVerifier.verify(jti)) { throw new InvalidJwtToken(); } - UserContext userContext = userService.getByUsername(subject); + String subject = jwsClaims.getBody().getSubject(); + + User user = userService.getByUsername(subject).orElseThrow(() -> new UsernameNotFoundException("User not found: " + subject)); + + if (user.getRoles() == null) throw new InsufficientAuthenticationException("User has no roles assigned"); + List authorities = user.getRoles().stream() + .map(authority -> new SimpleGrantedAuthority(authority.getRole().authority())) + .collect(Collectors.toList()); + + UserContext userContext = UserContext.create(user.getUsername(), authorities); return tokenFactory.createSafeToken(userContext); } diff --git a/src/main/java/com/svlada/security/model/JwtTokenFactory.java b/src/main/java/com/svlada/security/model/JwtTokenFactory.java index 1098ea7..e9a393a 100644 --- a/src/main/java/com/svlada/security/model/JwtTokenFactory.java +++ b/src/main/java/com/svlada/security/model/JwtTokenFactory.java @@ -1,6 +1,8 @@ package com.svlada.security.model; +import java.util.Arrays; import java.util.UUID; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; @@ -40,11 +42,16 @@ public class JwtTokenFactory { if (StringUtils.isBlank(userContext.getUsername())) { throw new IllegalArgumentException("Cannot create JWT Token without username"); } - - DateTime currentTime = new DateTime(); + + if (userContext.getAuthorities() == null || userContext.getAuthorities().isEmpty()) { + throw new IllegalArgumentException("User doesn't have any privileges"); + } Claims claims = Jwts.claims().setSubject(userContext.getUsername()); + claims.put("scopes", userContext.getAuthorities().stream().map(s -> s.toString()).collect(Collectors.toList())); + DateTime currentTime = new DateTime(); + String token = Jwts.builder() .setClaims(claims) .setIssuer(settings.getTokenIssuer()) @@ -56,27 +63,6 @@ public class JwtTokenFactory { return new SafeJwtToken(token, claims); } - public SafeJwtToken refreshToken(SafeJwtToken safeJwtToken) { - return null; - } - - public SafeJwtToken createSafeToken(String token, Claims claims) { - return new SafeJwtToken(token, claims); - } - - - /** - * Unsafe version of JWT token is created. - * - * WARNING: Token signature validation is not performed. - * - * @param tokenPayload - * @return unsafe version of JWT token. - */ - public UnsafeJwtToken createUnsafeToken(String tokenPayload) { - return new UnsafeJwtToken(tokenPayload); - } - public JwtToken createRefreshToken(UserContext userContext) { if (StringUtils.isBlank(userContext.getUsername())) { throw new IllegalArgumentException("Cannot create JWT Token without username"); @@ -85,6 +71,7 @@ public class JwtTokenFactory { DateTime currentTime = new DateTime(); Claims claims = Jwts.claims().setSubject(userContext.getUsername()); + claims.put("scopes", Arrays.asList(Scopes.REFRESH_TOKEN)); String token = Jwts.builder() .setClaims(claims) @@ -97,4 +84,16 @@ public class JwtTokenFactory { return new SafeJwtToken(token, claims); } + + /** + * Unsafe version of JWT token is created. + * + * WARNING: Token signature validation is not performed. + * + * @param tokenPayload + * @return unsafe version of JWT token. + */ + public UnsafeJwtToken createUnsafeToken(String tokenPayload) { + return new UnsafeJwtToken(tokenPayload); + } } diff --git a/src/main/java/com/svlada/security/model/Scopes.java b/src/main/java/com/svlada/security/model/Scopes.java new file mode 100644 index 0000000..cef70df --- /dev/null +++ b/src/main/java/com/svlada/security/model/Scopes.java @@ -0,0 +1,16 @@ +package com.svlada.security.model; + +/** + * Scopes + * + * @author vladimir.stankovic + * + * Aug 18, 2016 + */ +public enum Scopes { + REFRESH_TOKEN; + + public String authority() { + return "ROLE_" + this.name(); + } +} diff --git a/src/main/java/com/svlada/security/model/UserContext.java b/src/main/java/com/svlada/security/model/UserContext.java index 80ab314..4b9930f 100644 --- a/src/main/java/com/svlada/security/model/UserContext.java +++ b/src/main/java/com/svlada/security/model/UserContext.java @@ -1,8 +1,11 @@ package com.svlada.security.model; import java.util.List; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; /** * @@ -14,10 +17,15 @@ public class UserContext { private final String username; private final List authorities; - public UserContext(String username, List authorities) { + private UserContext(String username, List authorities) { this.username = username; this.authorities = authorities; } + + public static UserContext create(String username, List authorities) { + if (StringUtils.isBlank(username)) throw new IllegalArgumentException("Username is blank: " + username); + return new UserContext(username, authorities); + } public String getUsername() { return username; diff --git a/src/main/java/com/svlada/security/model/UserRole.java b/src/main/java/com/svlada/security/model/UserRole.java deleted file mode 100644 index ee243c9..0000000 --- a/src/main/java/com/svlada/security/model/UserRole.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.svlada.security.model; - -/** - * Enumeration of user Roles. - * - * @author vladimir.stankovic - * - * Aug 3, 2016 - */ -public enum UserRole { - ADMIN, INSTRUCTOR, PARTICIPANT, SUPERADMIN; - - public String authority() { - return "ROLE_" + this.name(); - } -} diff --git a/src/main/java/com/svlada/user/repository/UserRepository.java b/src/main/java/com/svlada/user/repository/UserRepository.java index 389204a..7e769b4 100644 --- a/src/main/java/com/svlada/user/repository/UserRepository.java +++ b/src/main/java/com/svlada/user/repository/UserRepository.java @@ -1,6 +1,10 @@ package com.svlada.user.repository; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import com.svlada.entity.User; @@ -12,5 +16,6 @@ import com.svlada.entity.User; * Aug 16, 2016 */ public interface UserRepository extends JpaRepository { - + @Query("select u from User u left join fetch u.roles r where u.username=:username") + public Optional findByUsername(@Param("username") String username); } diff --git a/src/main/java/com/svlada/user/service/DatabaseUserService.java b/src/main/java/com/svlada/user/service/DatabaseUserService.java index fa4fdd5..1d4318f 100644 --- a/src/main/java/com/svlada/user/service/DatabaseUserService.java +++ b/src/main/java/com/svlada/user/service/DatabaseUserService.java @@ -1,16 +1,12 @@ package com.svlada.user.service; -import java.util.ArrayList; -import java.util.List; +import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Service; +import com.svlada.entity.User; import com.svlada.security.UserService; -import com.svlada.security.model.UserContext; -import com.svlada.security.model.UserRole; import com.svlada.user.repository.UserRepository; /** @@ -29,21 +25,12 @@ public class DatabaseUserService implements UserService { this.userRepository = userRepository; } - @Override - public UserContext getByUsernameAndPassword(String username, String password) { - List authorities = new ArrayList(); - authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.authority())); - return new UserContext(username, authorities); - } - - @Override - public UserContext getByUsername(String username) { - List authorities = new ArrayList(); - authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.authority())); - return new UserContext(username, authorities); - } - public UserRepository getUserRepository() { return userRepository; } + + @Override + public Optional getByUsername(String username) { + return this.userRepository.findByUsername(username); + } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 27e0a7d..d0e3fc7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,7 +1,8 @@ server.port: 9966 spring.profiles: default demo.security.jwt: - tokenExpirationTime: 2 # Number of minutes + tokenExpirationTime: 15 # Number of minutes + refreshTokenExpTime: 60 # Minutes tokenIssuer: http://svlada.com tokenSigningKey: xm8EV6Hy5RMFK4EEACIDAwQus diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 29469e6..ee3a6b5 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1 +1,3 @@ -insert into APP_USER(ID, PASSWORD, ROLE, USERNAME) values(1, 'test', 'ADMIN', 'svlada@gmail.com'); \ No newline at end of file +insert into APP_USER(ID, PASSWORD, USERNAME) values(1, '$2a$10$bnC26zz//2cavYoSCrlHdecWF8tkGfPodlHcYwlACBBwJvcEf0p2G', 'svlada@gmail.com'); +insert into USER_ROLE(APP_USER_ID, ROLE) values(1, 'ADMIN'); +insert into USER_ROLE(APP_USER_ID, ROLE) values(1, 'PREMIUM_MEMBER'); \ No newline at end of file