JWT Token
This commit is contained in:
parent
0c0dffc6af
commit
4fce30fdc7
13
.idea/libraries/Maven__io_jsonwebtoken_jjwt_0_9_1.xml
Normal file
13
.idea/libraries/Maven__io_jsonwebtoken_jjwt_0_9_1.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: io.jsonwebtoken:jjwt:0.9.1">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/io/jsonwebtoken/jjwt/0.9.1/jjwt-0.9.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/io/jsonwebtoken/jjwt/0.9.1/jjwt-0.9.1-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/io/jsonwebtoken/jjwt/0.9.1/jjwt-0.9.1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
@ -2,27 +2,20 @@
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="47c3fbf4-4238-47d3-9ffa-fcd23da4e01e" name="Default Changelist" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/.idea/libraries/Maven__org_attoparser_attoparser_2_0_5_RELEASE.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_thymeleaf_2_3_0_RELEASE.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/libraries/Maven__org_thymeleaf_extras_thymeleaf_extras_java8time_3_0_4_RELEASE.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/libraries/Maven__org_thymeleaf_thymeleaf_3_0_11_RELEASE.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/libraries/Maven__org_thymeleaf_thymeleaf_spring5_3_0_11_RELEASE.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/libraries/Maven__org_unbescape_unbescape_1_1_6_RELEASE.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/controller/UserController.kt" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/resources/templates/register.html" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/libraries/Maven__io_jsonwebtoken_jjwt_0_9_1.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtAuthenticationEntryPoint.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtRequest.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtRequestFilter.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtResponse.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtTokenUtil.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/jdbc.iml" beforeDir="false" afterPath="$PROJECT_DIR$/jdbc.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/config/WebConfig.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/config/WebConfig.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/security/User.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/security/User.kt" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/security/UserDetailServiceImpl.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/security/UserDetailServiceImpl.kt" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/security/UserPrincipal.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/com/chantha/jdbc/security/UserPrincipal.kt" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/resources/application.properties" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/application.properties" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/target/classes/application.properties" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/application.properties" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/target/classes/com/chantha/jdbc/config/WebConfig.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/chantha/jdbc/config/WebConfig.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/target/classes/com/chantha/jdbc/security/User.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/chantha/jdbc/security/User.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/target/classes/com/chantha/jdbc/security/UserDetailServiceImpl.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/chantha/jdbc/security/UserDetailServiceImpl.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/target/classes/com/chantha/jdbc/security/UserPrincipal.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/chantha/jdbc/security/UserPrincipal.class" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@ -33,11 +26,11 @@
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Interface" />
|
||||
<option value="Class" />
|
||||
<option value="Kotlin Class" />
|
||||
<option value="Kotlin Interface" />
|
||||
<option value="HTML File" />
|
||||
<option value="Kotlin File" />
|
||||
<option value="Class" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
@ -71,7 +64,7 @@
|
||||
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="aspect.path.notification.shown" value="true" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/../springInterview" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/../spring-boot-react-oauth2-social-login-demo/spring-social" />
|
||||
<property name="restartRequiresConfirmation" value="false" />
|
||||
</component>
|
||||
<component name="RecentsManager">
|
||||
@ -112,7 +105,7 @@
|
||||
<workItem from="1589774040527" duration="72000" />
|
||||
<workItem from="1589788206287" duration="4024000" />
|
||||
<workItem from="1589857721932" duration="2546000" />
|
||||
<workItem from="1589862025987" duration="12626000" />
|
||||
<workItem from="1589862025987" duration="17207000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary=""Add Spring Security to project"">
|
||||
<created>1589796661163</created>
|
||||
@ -140,6 +133,10 @@
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state x="690" y="276" key="#com.intellij.codeInsight.editorActions.RestoreReferencesDialog/0.0.1920.1040@0.0.1920.1040" timestamp="1589601961718" />
|
||||
<state x="414" y="176" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1589880612427">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state x="414" y="176" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.0.1920.1040@0.0.1920.1040" timestamp="1589880612427" />
|
||||
<state x="765" y="197" key="#com.intellij.ide.util.MemberChooser" timestamp="1589863580998">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
@ -160,42 +157,42 @@
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state x="508" y="29" key="CommitChangelistDialog2/0.0.1920.1040@0.0.1920.1040" timestamp="1589796659997" />
|
||||
<state x="740" y="276" key="FileChooserDialogImpl" timestamp="1589873287289">
|
||||
<state x="740" y="276" key="FileChooserDialogImpl" timestamp="1589879048291">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state x="740" y="276" key="FileChooserDialogImpl/0.0.1920.1040@0.0.1920.1040" timestamp="1589873287289" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.bottom" timestamp="1589876503739">
|
||||
<state x="740" y="276" key="FileChooserDialogImpl/0.0.1920.1040@0.0.1920.1040" timestamp="1589879048291" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.bottom" timestamp="1589881169863">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1589876503739" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.center" timestamp="1589876503738">
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1589881169863" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.center" timestamp="1589881169862">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.center/0.0.1920.1040@0.0.1920.1040" timestamp="1589876503738" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.left" timestamp="1589876503738">
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.center/0.0.1920.1040@0.0.1920.1040" timestamp="1589881169862" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.left" timestamp="1589881169862">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.left/0.0.1920.1040@0.0.1920.1040" timestamp="1589876503738" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.right" timestamp="1589876503739">
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.left/0.0.1920.1040@0.0.1920.1040" timestamp="1589881169862" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.right" timestamp="1589881169863">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.right/0.0.1920.1040@0.0.1920.1040" timestamp="1589876503739" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.bottom" timestamp="1589876503739">
|
||||
<state width="1877" height="420" key="GridCell.Tab.0.right/0.0.1920.1040@0.0.1920.1040" timestamp="1589881169863" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.bottom" timestamp="1589881169863">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1589876503739" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.center" timestamp="1589876503739">
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1589881169863" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.center" timestamp="1589881169863">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.center/0.0.1920.1040@0.0.1920.1040" timestamp="1589876503739" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.left" timestamp="1589876503739">
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.center/0.0.1920.1040@0.0.1920.1040" timestamp="1589881169863" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.left" timestamp="1589881169863">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.left/0.0.1920.1040@0.0.1920.1040" timestamp="1589876503739" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.right" timestamp="1589876503739">
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.left/0.0.1920.1040@0.0.1920.1040" timestamp="1589881169863" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.right" timestamp="1589881169863">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.right/0.0.1920.1040@0.0.1920.1040" timestamp="1589876503739" />
|
||||
<state width="1877" height="420" key="GridCell.Tab.1.right/0.0.1920.1040@0.0.1920.1040" timestamp="1589881169863" />
|
||||
<state width="1877" height="326" key="GridCell.Tab.2.bottom" timestamp="1589796703748">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
@ -224,9 +221,9 @@
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state x="616" y="240" key="run.anything.popup/0.0.1920.1040@0.0.1920.1040" timestamp="1589796621453" />
|
||||
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup" timestamp="1589874332627">
|
||||
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup" timestamp="1589877750441">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup/0.0.1920.1040@0.0.1920.1040" timestamp="1589874332627" />
|
||||
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup/0.0.1920.1040@0.0.1920.1040" timestamp="1589877750441" />
|
||||
</component>
|
||||
</project>
|
1
jdbc.iml
1
jdbc.iml
@ -176,5 +176,6 @@
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.2.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.2.6.RELEASE" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
|
||||
</component>
|
||||
</module>
|
5
pom.xml
5
pom.xml
@ -77,6 +77,11 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>0.9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.chantha.jdbc.config;
|
||||
|
||||
import com.chantha.jdbc.utils.jwt.JwtRequestFilter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -13,6 +14,7 @@ import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
@Configuration
|
||||
@ -21,7 +23,8 @@ public class WebConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private final UserDetailsService userDetailsService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private JwtRequestFilter jwtRequestFilter;
|
||||
|
||||
@Autowired
|
||||
public WebConfig(UserDetailsService userDetailsService){
|
||||
@ -41,6 +44,7 @@ public class WebConfig extends WebSecurityConfigurerAdapter {
|
||||
.antMatchers("/register").permitAll()
|
||||
.antMatchers("/**").hasAnyRole("ADMIN");
|
||||
http.csrf().disable();
|
||||
http.addFilterBefore(jwtRequestFilter,UsernamePasswordAuthenticationFilter.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -3,11 +3,12 @@ package com.chantha.jdbc.security
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.security.core.userdetails.UserDetails
|
||||
import org.springframework.security.core.userdetails.UserDetailsService
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UserDetailServiceImpl @Autowired constructor(private val userRepo: UserRepo):UserDetailsService {
|
||||
@Throws(Exception::class)
|
||||
@Throws(UsernameNotFoundException::class)
|
||||
override fun loadUserByUsername(p0: String?): UserDetails {
|
||||
val user = userRepo.findByUsername(p0!!)
|
||||
return UserPrincipal(user)
|
||||
|
@ -0,0 +1,19 @@
|
||||
package com.chantha.jdbc.utils.jwt;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {
|
||||
private static final long serialVersionUID = -7858869558953243875L;
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException authException) throws IOException {
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
|
||||
}
|
||||
}
|
28
src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtRequest.java
Normal file
28
src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtRequest.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.chantha.jdbc.utils.jwt;
|
||||
|
||||
import java.io.Serializable;
|
||||
public class JwtRequest implements Serializable {
|
||||
private static final long serialVersionUID = 5926468583005150707L;
|
||||
private String username;
|
||||
private String password;
|
||||
//need default constructor for JSON Parsing
|
||||
public JwtRequest()
|
||||
{
|
||||
}
|
||||
public JwtRequest(String username, String password) {
|
||||
this.setUsername(username);
|
||||
this.setPassword(password);
|
||||
}
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.chantha.jdbc.utils.jwt;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import com.chantha.jdbc.security.UserDetailServiceImpl;
|
||||
import io.jsonwebtoken.ExpiredJwtException;
|
||||
@Component
|
||||
public class JwtRequestFilter extends OncePerRequestFilter {
|
||||
|
||||
@Autowired
|
||||
private UserDetailServiceImpl jwtUserDetailsService;
|
||||
|
||||
@Autowired
|
||||
private JwtTokenUtil jwtTokenUtil;
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
throws ServletException, IOException {
|
||||
final String requestTokenHeader = request.getHeader("Authorization");
|
||||
String username = null;
|
||||
String jwtToken = null;
|
||||
// JWT Token is in the form "Bearer token". Remove Bearer word and get
|
||||
// only the Token
|
||||
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
|
||||
jwtToken = requestTokenHeader.substring(7);
|
||||
try {
|
||||
username = jwtTokenUtil.getUsernameFromToken(jwtToken);
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("Unable to get JWT Token");
|
||||
} catch (ExpiredJwtException e) {
|
||||
System.out.println("JWT Token has expired");
|
||||
}
|
||||
} else {
|
||||
logger.warn("JWT Token does not begin with Bearer String");
|
||||
}
|
||||
// Once we get the token validate it.
|
||||
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
|
||||
// if token is valid configure Spring Security to manually set
|
||||
// authentication
|
||||
if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
|
||||
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
|
||||
userDetails, null, userDetails.getAuthorities());
|
||||
usernamePasswordAuthenticationToken
|
||||
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
// After setting the Authentication in the context, we specify
|
||||
// that the current user is authenticated. So it passes the
|
||||
// Spring Security Configurations successfully.
|
||||
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
|
||||
}
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
16
src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtResponse.java
Normal file
16
src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtResponse.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.chantha.jdbc.utils.jwt;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JwtResponse implements Serializable {
|
||||
private static final long serialVersionUID = -8091879091924046844L;
|
||||
private final String jwttoken;
|
||||
|
||||
public JwtResponse(String jwttoken) {
|
||||
this.jwttoken = jwttoken;
|
||||
}
|
||||
public String getToken() {
|
||||
return this.jwttoken;
|
||||
}
|
||||
|
||||
}
|
63
src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtTokenUtil.java
Normal file
63
src/main/kotlin/com/chantha/jdbc/utils/jwt/JwtTokenUtil.java
Normal file
@ -0,0 +1,63 @@
|
||||
package com.chantha.jdbc.utils.jwt;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Component
|
||||
public class JwtTokenUtil implements Serializable {
|
||||
private static final long serialVersionUID = -2550185165626007488L;
|
||||
public static final long JWT_TOKEN_VALIDITY = 5 * 60 * 60;
|
||||
@Value("${jwt.secret}")
|
||||
private String secret;
|
||||
//retrieve username from jwt token
|
||||
public String getUsernameFromToken(String token) {
|
||||
return getClaimFromToken(token, Claims::getSubject);
|
||||
}
|
||||
//retrieve expiration date from jwt token
|
||||
public Date getExpirationDateFromToken(String token) {
|
||||
return getClaimFromToken(token, Claims::getExpiration);
|
||||
}
|
||||
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
|
||||
final Claims claims = getAllClaimsFromToken(token);
|
||||
return claimsResolver.apply(claims);
|
||||
}
|
||||
//for retrieveing any information from token we will need the secret key
|
||||
private Claims getAllClaimsFromToken(String token) {
|
||||
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
|
||||
}
|
||||
//check if the token has expired
|
||||
private Boolean isTokenExpired(String token) {
|
||||
final Date expiration = getExpirationDateFromToken(token);
|
||||
return expiration.before(new Date());
|
||||
}
|
||||
//generate token for user
|
||||
public String generateToken(UserDetails userDetails) {
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
return doGenerateToken(claims, userDetails.getUsername());
|
||||
}
|
||||
//while creating the token -
|
||||
//1. Define claims of the token, like Issuer, Expiration, Subject, and the ID
|
||||
//2. Sign the JWT using the HS512 algorithm and secret key.
|
||||
//3. According to JWS Compact Serialization(https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-3.1)
|
||||
// compaction of the JWT to a URL-safe string
|
||||
private String doGenerateToken(Map<String, Object> claims, String subject) {
|
||||
return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
|
||||
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
|
||||
.signWith(SignatureAlgorithm.HS512, secret).compact();
|
||||
}
|
||||
//validate token
|
||||
public Boolean validateToken(String token, UserDetails userDetails) {
|
||||
final String username = getUsernameFromToken(token);
|
||||
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
|
||||
}
|
||||
}
|
@ -7,6 +7,8 @@ spring.jpa.open-in-view=true
|
||||
server.port=8081
|
||||
spring.thymeleaf.cache=true
|
||||
|
||||
jwt.secret=javainuse
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -7,6 +7,8 @@ spring.jpa.open-in-view=true
|
||||
server.port=8081
|
||||
spring.thymeleaf.cache=true
|
||||
|
||||
jwt.secret=javainuse
|
||||
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
target/classes/com/chantha/jdbc/utils/jwt/JwtRequest.class
Normal file
BIN
target/classes/com/chantha/jdbc/utils/jwt/JwtRequest.class
Normal file
Binary file not shown.
BIN
target/classes/com/chantha/jdbc/utils/jwt/JwtRequestFilter.class
Normal file
BIN
target/classes/com/chantha/jdbc/utils/jwt/JwtRequestFilter.class
Normal file
Binary file not shown.
BIN
target/classes/com/chantha/jdbc/utils/jwt/JwtResponse.class
Normal file
BIN
target/classes/com/chantha/jdbc/utils/jwt/JwtResponse.class
Normal file
Binary file not shown.
BIN
target/classes/com/chantha/jdbc/utils/jwt/JwtTokenUtil.class
Normal file
BIN
target/classes/com/chantha/jdbc/utils/jwt/JwtTokenUtil.class
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user