├── .gitignore ├── README.md ├── build.gradle ├── class diagram.PNG ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main ├── java │ └── com │ │ ├── SpringBootWebJwtApplication.java │ │ ├── configs │ │ └── security │ │ │ ├── JWTAuthenticationFilter.java │ │ │ ├── JWTAuthorizationFilter.java │ │ │ ├── JwtAuthenticationEntryPoint.java │ │ │ ├── JwtOutils.java │ │ │ ├── MyBCryptPasswordEncoder.java │ │ │ ├── SecurityConstants.java │ │ │ ├── UserDetailsServiceImpl.java │ │ │ └── WebSecurity.java │ │ ├── controllers │ │ ├── TestProvilageController.java │ │ └── UserController.java │ │ ├── models │ │ ├── AuthRequest.java │ │ ├── AuthResponse.java │ │ ├── Privilege.java │ │ ├── Role.java │ │ └── User.java │ │ ├── repositories │ │ ├── PrivilageRepository.java │ │ ├── RoleRepository.java │ │ └── UserRepository.java │ │ └── services │ │ ├── ProfileSevices.java │ │ └── SecurityServices.java └── resources │ └── application.properties └── test └── java └── com └── SpringBootWebJwtApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JWT-Role-and-Permission-Based-Authorization-with-Spring-boot-Security 2 | JWT Role and Permission Based Authorization with Spring boot Security 3 | 4 | 5 | # Class Diagram 6 | 7 | ![alt text](https://github.com/benayadmohamed/JWT-Role-and-Permission-Based-Authorization-with-Spring-boot-Security/blob/master/class%20diagram.PNG) 8 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.1.9.RELEASE' 3 | id 'io.spring.dependency-management' version '1.0.8.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'com' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 17 | implementation 'org.springframework.boot:spring-boot-starter-security' 18 | implementation 'org.springframework.boot:spring-boot-starter-web' 19 | implementation 'com.auth0:java-jwt:3.8.0' 20 | implementation 'org.projectlombok:lombok:1.18.8' 21 | runtimeOnly 'mysql:mysql-connector-java' 22 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 23 | testImplementation 'org.springframework.security:spring-security-test' 24 | } 25 | -------------------------------------------------------------------------------- /class diagram.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benayadmohamed/JWT-Role-and-Permission-Based-Authorization-with-Spring-boot-Security/428a650cd9a9a53560f736932d097b813ce4e8ff/class diagram.PNG -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benayadmohamed/JWT-Role-and-Permission-Based-Authorization-with-Spring-boot-Security/428a650cd9a9a53560f736932d097b813ce4e8ff/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring-boot-web-jwt' 2 | -------------------------------------------------------------------------------- /src/main/java/com/SpringBootWebJwtApplication.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import com.configs.security.MyBCryptPasswordEncoder; 4 | import com.models.Privilege; 5 | import com.models.Role; 6 | import com.models.User; 7 | import com.repositories.PrivilageRepository; 8 | import com.repositories.RoleRepository; 9 | import com.repositories.UserRepository; 10 | import com.services.SecurityServices; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.boot.CommandLineRunner; 13 | import org.springframework.boot.SpringApplication; 14 | import org.springframework.boot.autoconfigure.SpringBootApplication; 15 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 16 | 17 | import java.util.Arrays; 18 | import java.util.Collections; 19 | import java.util.stream.Collectors; 20 | 21 | @SpringBootApplication 22 | public class SpringBootWebJwtApplication implements CommandLineRunner { 23 | 24 | @Autowired 25 | UserRepository userRepository; 26 | @Autowired 27 | private RoleRepository roleRepository; 28 | @Autowired 29 | private PrivilageRepository privilageRepository; 30 | @Autowired 31 | private MyBCryptPasswordEncoder myBCryptPasswordEncoder; 32 | 33 | public static void main(String[] args) { 34 | SpringApplication.run(SpringBootWebJwtApplication.class, args); 35 | } 36 | 37 | @Override 38 | public void run(String... args) throws Exception { 39 | roleRepository.deleteAll(); 40 | privilageRepository.deleteAll(); 41 | userRepository.deleteAll(); 42 | 43 | Privilege EDIT_PROFILE = privilageRepository.save(new Privilege("EDIT_PROFILE")); 44 | Privilege READ_PROFILE = privilageRepository.save(new Privilege("READ_PROFILE")); 45 | Privilege DELETE_PROFILE = privilageRepository.save(new Privilege("DELETE_PROFILE")); 46 | 47 | Privilege EDIT_USE = privilageRepository.save(new Privilege("EDIT_USE")); 48 | Privilege READ_USE = privilageRepository.save(new Privilege("READ_USE")); 49 | Privilege DELETE_USE = privilageRepository.save(new Privilege("DELETE_USE")); 50 | 51 | Role ROLE_ADMIN = roleRepository.save(new Role("ROLE_ADMIN", 52 | Arrays.asList( 53 | EDIT_PROFILE, 54 | READ_PROFILE, 55 | DELETE_PROFILE, 56 | EDIT_USE, 57 | READ_USE, 58 | DELETE_USE 59 | ))); 60 | Role ROLE_USER = roleRepository.save(new Role("ROLE_USER", Arrays.asList( 61 | READ_PROFILE, 62 | READ_USE 63 | ))); 64 | userRepository.save(new User( 65 | "admin", 66 | myBCryptPasswordEncoder.encode("0000"), 67 | Arrays.asList(ROLE_ADMIN, ROLE_USER) 68 | )); 69 | userRepository.save(new User( 70 | "user", 71 | myBCryptPasswordEncoder.encode("0000"), 72 | Arrays.asList(ROLE_USER) 73 | )); 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/configs/security/JWTAuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package com.configs.security; 2 | 3 | import com.auth0.jwt.JWT; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.models.AuthResponse; 6 | import com.models.User; 7 | import org.springframework.http.*; 8 | import org.springframework.security.authentication.AuthenticationManager; 9 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 10 | import org.springframework.security.core.Authentication; 11 | import org.springframework.security.core.AuthenticationException; 12 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 13 | 14 | import javax.servlet.FilterChain; 15 | import javax.servlet.ServletException; 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpServletResponse; 18 | import java.io.IOException; 19 | 20 | public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { 21 | private AuthenticationManager authenticationManager; 22 | private JwtOutils jwtOutils; 23 | 24 | public JWTAuthenticationFilter(AuthenticationManager authenticationManager, JwtOutils jwtOutils) { 25 | this.authenticationManager = authenticationManager; 26 | this.jwtOutils = jwtOutils; 27 | } 28 | 29 | @Override 30 | public Authentication attemptAuthentication(HttpServletRequest req, 31 | HttpServletResponse res) throws AuthenticationException { 32 | try { 33 | System.out.println("req login = [" + req + "], res = [" + res + "]"); 34 | User creds = new ObjectMapper() 35 | .readValue(req.getInputStream(), User.class); 36 | // passser le mot de passe au UserDetailsService pour recuperer l'utilisateur s'il existe 37 | return authenticationManager.authenticate( 38 | new UsernamePasswordAuthenticationToken( 39 | creds.getUsername(), 40 | creds.getPassword(), 41 | null) 42 | ); 43 | } catch (IOException e) { 44 | throw new RuntimeException("not authorizer"); 45 | } 46 | } 47 | 48 | @Override 49 | protected void successfulAuthentication(HttpServletRequest req, 50 | HttpServletResponse res, 51 | FilterChain chain, 52 | Authentication auth) 53 | throws IOException, ServletException { 54 | 55 | String token = jwtOutils.create((User) auth.getPrincipal()); 56 | ObjectMapper mapper = new ObjectMapper(); 57 | res.setContentType(MediaType.APPLICATION_JSON_VALUE); 58 | res.getWriter().print( 59 | mapper.writeValueAsString(new AuthResponse(token))); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/configs/security/JWTAuthorizationFilter.java: -------------------------------------------------------------------------------- 1 | package com.configs.security; 2 | 3 | import com.auth0.jwt.JWT; 4 | import com.auth0.jwt.algorithms.Algorithm; 5 | import com.auth0.jwt.exceptions.AlgorithmMismatchException; 6 | import com.auth0.jwt.exceptions.SignatureVerificationException; 7 | import com.auth0.jwt.exceptions.TokenExpiredException; 8 | import com.auth0.jwt.interfaces.DecodedJWT; 9 | import com.models.Privilege; 10 | import com.models.User; 11 | import com.repositories.UserRepository; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.beans.factory.annotation.Value; 14 | import org.springframework.security.authentication.AuthenticationManager; 15 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 16 | import org.springframework.security.core.context.SecurityContextHolder; 17 | import org.springframework.security.core.userdetails.UserDetails; 18 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; 19 | 20 | import javax.servlet.FilterChain; 21 | import javax.servlet.ServletException; 22 | import javax.servlet.http.HttpServletRequest; 23 | import javax.servlet.http.HttpServletResponse; 24 | import java.io.IOException; 25 | import java.util.ArrayList; 26 | import java.util.Collection; 27 | import java.util.Collections; 28 | import java.util.List; 29 | 30 | import static com.configs.security.SecurityConstants.HEADER_STRING; 31 | import static com.configs.security.SecurityConstants.TOKEN_PREFIX; 32 | 33 | public class JWTAuthorizationFilter extends BasicAuthenticationFilter { 34 | 35 | private JwtOutils jwtOutils; 36 | 37 | public JWTAuthorizationFilter(AuthenticationManager authManager, JwtOutils jwtOutils) { 38 | super(authManager); 39 | this.jwtOutils = jwtOutils; 40 | } 41 | 42 | 43 | @Override 44 | protected void doFilterInternal(HttpServletRequest req, 45 | HttpServletResponse res, 46 | FilterChain chain) throws IOException, ServletException { 47 | String header = req.getHeader(HEADER_STRING); 48 | 49 | if (header == null || !header.startsWith(TOKEN_PREFIX)) { 50 | chain.doFilter(req, res); 51 | return; 52 | } 53 | 54 | UsernamePasswordAuthenticationToken authentication = getAuthentication(req); 55 | 56 | SecurityContextHolder.getContext().setAuthentication(authentication); 57 | chain.doFilter(req, res); 58 | } 59 | 60 | private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) { 61 | String token = request.getHeader(HEADER_STRING); 62 | if (token != null) { 63 | // parse the token. 64 | String user = null; 65 | try { 66 | DecodedJWT decodedJWT = jwtOutils.verify(token); 67 | user = decodedJWT.getSubject(); 68 | Collection privilegeCollections = new ArrayList<>(); 69 | String[] privileges = decodedJWT.getClaim("privileges").asArray(String.class); 70 | for (String s : privileges) { 71 | privilegeCollections.add(new Privilege(s)); 72 | } 73 | System.out.println("request = [" + privilegeCollections + "]"); 74 | return new UsernamePasswordAuthenticationToken(user, null, privilegeCollections); 75 | } catch (AlgorithmMismatchException e) { 76 | logger.error("Algorithm Mismatch Exception", e); 77 | } catch (TokenExpiredException e) { 78 | logger.warn("Token Expired Exception", e); 79 | } catch (SignatureVerificationException e) { 80 | logger.error("Signature Verification Exception."); 81 | } 82 | } 83 | return null; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/configs/security/JwtAuthenticationEntryPoint.java: -------------------------------------------------------------------------------- 1 | package com.configs.security; 2 | 3 | import org.springframework.security.core.AuthenticationException; 4 | import org.springframework.security.web.AuthenticationEntryPoint; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.servlet.ServletException; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.io.IOException; 11 | 12 | @Component 13 | public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { 14 | 15 | 16 | @Override 17 | public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { 18 | httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); 19 | } 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/configs/security/JwtOutils.java: -------------------------------------------------------------------------------- 1 | package com.configs.security; 2 | 3 | import com.auth0.jwt.JWT; 4 | import com.auth0.jwt.algorithms.Algorithm; 5 | import com.auth0.jwt.exceptions.JWTVerificationException; 6 | import com.auth0.jwt.interfaces.DecodedJWT; 7 | import com.models.Privilege; 8 | import com.models.Role; 9 | import com.models.User; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.Collection; 14 | import java.util.Date; 15 | import java.util.stream.Collectors; 16 | 17 | import static com.auth0.jwt.algorithms.Algorithm.HMAC512; 18 | import static com.configs.security.SecurityConstants.TOKEN_PREFIX; 19 | 20 | @Component 21 | public class JwtOutils { 22 | @Value("${springbootwebfluxjjwt.jjwt.secret}") 23 | private String secret; 24 | @Value("${springbootwebfluxjjwt.jjwt.expiration}") 25 | private long expiration; 26 | 27 | 28 | public DecodedJWT verify(String token) throws JWTVerificationException { 29 | return JWT.require( 30 | // Algorithm.RSA512(new ) 31 | Algorithm.HMAC512(secret.getBytes()) 32 | ) 33 | .build() 34 | .verify(token.replace(TOKEN_PREFIX, "")); 35 | } 36 | 37 | public String create(User user) throws JWTVerificationException { 38 | Collection authorities = user.getAuthorities(); 39 | String[] privileges = authorities.stream() 40 | .map(privilege -> privilege.getAuthority()) 41 | .distinct().toArray(String[]::new); 42 | return JWT.create() 43 | .withSubject(user.getUsername()) 44 | .withArrayClaim("privileges", privileges) 45 | .withExpiresAt(new Date(System.currentTimeMillis() + expiration)) 46 | .sign(HMAC512(secret.getBytes())); 47 | // .sign(HMAC512(secret.getBytes())); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/configs/security/MyBCryptPasswordEncoder.java: -------------------------------------------------------------------------------- 1 | package com.configs.security; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.security.crypto.password.PasswordEncoder; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.crypto.SecretKeyFactory; 8 | import javax.crypto.spec.PBEKeySpec; 9 | import java.security.NoSuchAlgorithmException; 10 | import java.security.spec.InvalidKeySpecException; 11 | import java.util.Base64; 12 | 13 | @Component 14 | public class MyBCryptPasswordEncoder implements PasswordEncoder { 15 | 16 | 17 | @Value("${springbootwebfluxjjwt.password.encoder.secret}") 18 | private String secret; 19 | 20 | @Value("${springbootwebfluxjjwt.password.encoder.iteration}") 21 | private Integer iteration; 22 | 23 | @Value("${springbootwebfluxjjwt.password.encoder.keylength}") 24 | private Integer keylength; 25 | 26 | 27 | @Override 28 | public String encode(CharSequence cs) { 29 | try { 30 | byte[] result = 31 | SecretKeyFactory 32 | .getInstance("PBKDF2WithHmacSHA512") 33 | .generateSecret(new PBEKeySpec(cs.toString().toCharArray(), secret.getBytes(), iteration, keylength)) 34 | .getEncoded(); 35 | return Base64.getEncoder().encodeToString(result); 36 | } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) { 37 | throw new RuntimeException(ex); 38 | } 39 | } 40 | 41 | @Override 42 | public boolean matches(CharSequence cs, String string) { 43 | return encode(cs).equals(string); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/configs/security/SecurityConstants.java: -------------------------------------------------------------------------------- 1 | package com.configs.security; 2 | 3 | 4 | public class SecurityConstants { 5 | public static final String TOKEN_PREFIX = "Bearer "; 6 | public static final String HEADER_STRING = "Authorization"; 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/configs/security/UserDetailsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.configs.security; 2 | 3 | import com.models.User; 4 | import com.repositories.UserRepository; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 8 | import org.springframework.stereotype.Service; 9 | 10 | 11 | @Service 12 | public class UserDetailsServiceImpl implements UserDetailsService { 13 | private UserRepository UserRepository; 14 | 15 | public UserDetailsServiceImpl(com.repositories.UserRepository UserRepository) { 16 | this.UserRepository = UserRepository; 17 | } 18 | 19 | @Override 20 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 21 | User User = UserRepository.findByUsername(username); 22 | if (User == null) { 23 | throw new UsernameNotFoundException(username); 24 | } 25 | return User; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/configs/security/WebSecurity.java: -------------------------------------------------------------------------------- 1 | package com.configs.security; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.http.HttpMethod; 5 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 6 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 10 | import org.springframework.security.config.http.SessionCreationPolicy; 11 | import org.springframework.web.cors.CorsConfiguration; 12 | import org.springframework.web.cors.CorsConfigurationSource; 13 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 14 | 15 | @EnableGlobalMethodSecurity(prePostEnabled = true) 16 | @EnableWebSecurity 17 | public class WebSecurity extends WebSecurityConfigurerAdapter { 18 | private UserDetailsServiceImpl userDetailsService; 19 | private MyBCryptPasswordEncoder myBCryptPasswordEncoder; 20 | private final JwtOutils jwtOutils; 21 | private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; 22 | 23 | public WebSecurity(UserDetailsServiceImpl userDetailsService, MyBCryptPasswordEncoder myBCryptPasswordEncoder, JwtOutils jwtOutils, JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint) { 24 | this.userDetailsService = userDetailsService; 25 | this.myBCryptPasswordEncoder = myBCryptPasswordEncoder; 26 | this.jwtOutils = jwtOutils; 27 | this.jwtAuthenticationEntryPoint = jwtAuthenticationEntryPoint; 28 | } 29 | 30 | @Override 31 | protected void configure(HttpSecurity http) throws Exception { 32 | http.cors().and() 33 | .csrf().disable() 34 | .authorizeRequests() 35 | .antMatchers(HttpMethod.POST, "/sign-up", "/sign-in").permitAll() 36 | .anyRequest().authenticated() 37 | .and() 38 | .exceptionHandling() 39 | .authenticationEntryPoint(jwtAuthenticationEntryPoint) 40 | .and() 41 | //utiliser pour le login :: post localhost:8081/login 42 | .addFilter(new JWTAuthenticationFilter(authenticationManager(), jwtOutils)) 43 | // utliser pour verifier le token et extraitre les premissions 44 | .addFilter(new JWTAuthorizationFilter(authenticationManager(), jwtOutils)) 45 | // this disables session creation on Spring Security 46 | .sessionManagement() 47 | .sessionCreationPolicy(SessionCreationPolicy.STATELESS); 48 | } 49 | 50 | 51 | @Override 52 | public void configure(AuthenticationManagerBuilder auth) throws Exception { 53 | auth.userDetailsService(userDetailsService).passwordEncoder(myBCryptPasswordEncoder); 54 | } 55 | 56 | @Bean 57 | CorsConfigurationSource corsConfigurationSource() { 58 | final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 59 | source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); 60 | return source; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/controllers/TestProvilageController.java: -------------------------------------------------------------------------------- 1 | package com.controllers; 2 | 3 | import com.services.ProfileSevices; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.security.access.prepost.PreAuthorize; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | @RestController 10 | public class TestProvilageController { 11 | 12 | @Autowired 13 | private ProfileSevices profileSevices; 14 | 15 | @GetMapping("all") 16 | public String all() { 17 | return profileSevices.all(); 18 | } 19 | 20 | @GetMapping("edit") 21 | public String edit() { 22 | return profileSevices.edit(); 23 | } 24 | 25 | @GetMapping("read") 26 | public String read() { 27 | return profileSevices.read(); 28 | } 29 | 30 | @GetMapping("delete") 31 | public String delete() { 32 | return profileSevices.delete(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/controllers/UserController.java: -------------------------------------------------------------------------------- 1 | package com.controllers; 2 | 3 | import com.configs.security.JwtOutils; 4 | import com.configs.security.MyBCryptPasswordEncoder; 5 | import com.models.AuthRequest; 6 | import com.models.AuthResponse; 7 | import com.models.User; 8 | import com.repositories.UserRepository; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.http.HttpStatus; 11 | import org.springframework.http.ResponseEntity; 12 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 13 | import org.springframework.web.bind.annotation.PostMapping; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.RestController; 17 | 18 | @RestController 19 | @RequestMapping("") 20 | public class UserController { 21 | 22 | private com.repositories.UserRepository UserRepository; 23 | private MyBCryptPasswordEncoder myBCryptPasswordEncoder; 24 | @Autowired 25 | private com.repositories.UserRepository userRepository; 26 | @Autowired 27 | private JwtOutils jwtOutils; 28 | 29 | public UserController(UserRepository UserRepository, 30 | MyBCryptPasswordEncoder myBCryptPasswordEncoder) { 31 | this.UserRepository = UserRepository; 32 | this.myBCryptPasswordEncoder = myBCryptPasswordEncoder; 33 | } 34 | 35 | @PostMapping("/sign-in") 36 | public AuthResponse signIn(@RequestBody AuthRequest authRequest) { 37 | User user = userRepository.findByUsername(authRequest.username); 38 | if (user != null && myBCryptPasswordEncoder.matches(authRequest.password, user.getPassword())) { 39 | return new AuthResponse(jwtOutils.create(user)); 40 | } 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/models/AuthRequest.java: -------------------------------------------------------------------------------- 1 | package com.models; 2 | 3 | public class AuthRequest { 4 | public String username; 5 | public String password; 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/models/AuthResponse.java: -------------------------------------------------------------------------------- 1 | package com.models; 2 | 3 | import java.io.Serializable; 4 | import java.util.Collection; 5 | 6 | public class AuthResponse implements Serializable { 7 | private String token; 8 | 9 | public AuthResponse(String token) { 10 | this.token = token; 11 | } 12 | 13 | public String getToken() { 14 | return token; 15 | } 16 | 17 | public void setToken(String token) { 18 | this.token = token; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/models/Privilege.java: -------------------------------------------------------------------------------- 1 | package com.models; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | 10 | @Entity 11 | public class Privilege implements GrantedAuthority { 12 | @Id 13 | @GeneratedValue(strategy = GenerationType.IDENTITY) 14 | private long id; 15 | private String authority; 16 | 17 | public Privilege() { 18 | } 19 | 20 | public Privilege(String authority) { 21 | this.authority = authority; 22 | } 23 | 24 | public Privilege(long id, String authority) { 25 | this.authority = authority; 26 | this.id = id; 27 | } 28 | 29 | public long getId() { 30 | return id; 31 | } 32 | 33 | public void setId(long id) { 34 | this.id = id; 35 | } 36 | 37 | public void setAuthority(String authority) { 38 | this.authority = authority; 39 | } 40 | 41 | 42 | @Override 43 | public String getAuthority() { 44 | return authority; 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return "Privilege{" + 50 | "id=" + id + 51 | ", authority='" + authority + '\'' + 52 | '}'; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/models/Role.java: -------------------------------------------------------------------------------- 1 | package com.models; 2 | 3 | 4 | import javax.persistence.*; 5 | import java.util.ArrayList; 6 | import java.util.Collection; 7 | 8 | @Entity 9 | public class Role { 10 | @Id 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private long id; 13 | private String name; 14 | @ManyToMany(fetch = FetchType.EAGER) 15 | private Collection privileges = new ArrayList<>(); 16 | 17 | public static Role valueOf(String role) { 18 | return new Role(role); 19 | } 20 | 21 | public Role() { 22 | } 23 | 24 | public Role(String name) { 25 | this.name = name; 26 | } 27 | 28 | public Role(String name, Collection privileges) { 29 | this.name = name; 30 | this.privileges = privileges; 31 | } 32 | 33 | public long getId() { 34 | return id; 35 | } 36 | 37 | public void setId(long id) { 38 | this.id = id; 39 | } 40 | 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | public void setName(String name) { 46 | this.name = name; 47 | } 48 | 49 | public Collection getPrivileges() { 50 | return privileges; 51 | } 52 | 53 | public void setPrivileges(Collection privileges) { 54 | this.privileges = privileges; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/models/User.java: -------------------------------------------------------------------------------- 1 | package com.models; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | 6 | import javax.persistence.*; 7 | import java.util.ArrayList; 8 | import java.util.Collection; 9 | import java.util.List; 10 | 11 | @Entity 12 | @Table(name = "users") 13 | public class User implements UserDetails { 14 | @Id 15 | @GeneratedValue(strategy = GenerationType.IDENTITY) 16 | private long id; 17 | private String username; 18 | private String password; 19 | @ManyToMany(fetch = FetchType.EAGER) 20 | private Collection roles = new ArrayList<>(); 21 | 22 | public User() { 23 | } 24 | 25 | public User(String username, String password) { 26 | this.username = username; 27 | this.password = password; 28 | } 29 | 30 | public User(String username, String password, Collection roles) { 31 | this.username = username; 32 | this.password = password; 33 | this.roles = roles; 34 | } 35 | 36 | public long getId() { 37 | return id; 38 | } 39 | 40 | public String getUsername() { 41 | return username; 42 | } 43 | 44 | @Override 45 | public boolean isAccountNonExpired() { 46 | return true; 47 | } 48 | 49 | @Override 50 | public boolean isAccountNonLocked() { 51 | return true; 52 | } 53 | 54 | @Override 55 | public boolean isCredentialsNonExpired() { 56 | return true; 57 | } 58 | 59 | @Override 60 | public boolean isEnabled() { 61 | return true; 62 | } 63 | 64 | public void setUsername(String username) { 65 | this.username = username; 66 | } 67 | 68 | @Override 69 | public Collection getAuthorities() { 70 | List privileges = new ArrayList<>(); 71 | roles.forEach(role -> { 72 | privileges.addAll(role.getPrivileges()); 73 | }); 74 | return privileges; 75 | } 76 | 77 | public String getPassword() { 78 | return password; 79 | } 80 | 81 | public void setPassword(String password) { 82 | this.password = password; 83 | } 84 | 85 | public Collection getRoles() { 86 | return roles; 87 | } 88 | 89 | public void setRoles(Collection roles) { 90 | this.roles = roles; 91 | } 92 | 93 | @Override 94 | public String toString() { 95 | return "User{" + 96 | "id=" + id + 97 | ", username='" + username + '\'' + 98 | ", password='" + password + '\'' + 99 | ", roles=" + roles + 100 | '}'; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/repositories/PrivilageRepository.java: -------------------------------------------------------------------------------- 1 | package com.repositories; 2 | 3 | import com.models.Privilege; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface PrivilageRepository extends JpaRepository { 7 | Privilege findByAuthority(String authority); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/repositories/RoleRepository.java: -------------------------------------------------------------------------------- 1 | package com.repositories; 2 | 3 | import com.models.Role; 4 | import com.models.User; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | public interface RoleRepository extends JpaRepository { 8 | Role findByName(String name); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/repositories/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.repositories; 2 | 3 | import com.models.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface UserRepository extends JpaRepository { 7 | User findByUsername(String username); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/services/ProfileSevices.java: -------------------------------------------------------------------------------- 1 | package com.services; 2 | 3 | import org.springframework.security.access.prepost.PreAuthorize; 4 | import org.springframework.stereotype.Service; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | 7 | @Service 8 | public class ProfileSevices { 9 | @PreAuthorize("hasAuthority('EDIT_PROFILE') and hasAuthority('DELETE_PROFILE') and hasAuthority('READ_PROFILE')") 10 | public String all() { 11 | return "EDIT_PROFILE READ_PROFILE DELETE_PROFILE"; 12 | } 13 | 14 | @PreAuthorize("hasAuthority('EDIT_PROFILE')") 15 | public String edit() { 16 | return "EDIT_PROFILE"; 17 | } 18 | 19 | @PreAuthorize("hasAuthority('READ_PROFILE')") 20 | public String read() { 21 | return "READ_PROFILE"; 22 | } 23 | 24 | @PreAuthorize("hasAuthority('DELETE_PROFILE')") 25 | public String delete() { 26 | return "DELETE_PROFILE"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/services/SecurityServices.java: -------------------------------------------------------------------------------- 1 | package com.services; 2 | 3 | import com.configs.security.MyBCryptPasswordEncoder; 4 | import com.models.Privilege; 5 | import com.models.Role; 6 | import com.models.User; 7 | import com.repositories.PrivilageRepository; 8 | import com.repositories.RoleRepository; 9 | import com.repositories.UserRepository; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Service; 12 | 13 | @Service 14 | public class SecurityServices { 15 | 16 | 17 | @Autowired 18 | private UserRepository userRepository; 19 | @Autowired 20 | private RoleRepository roleRepository; 21 | 22 | @Autowired 23 | private MyBCryptPasswordEncoder myBCryptPasswordEncoder; 24 | 25 | @Autowired 26 | private PrivilageRepository privilageRepository; 27 | 28 | public void createUser(User user) { 29 | Role role = roleRepository.findByName("USER"); 30 | if (role == null) 31 | role = roleRepository.save(Role.valueOf("USER")); 32 | 33 | Privilege privilege = privilageRepository.findByAuthority("READ_PROFILE"); 34 | if (privilege == null) 35 | privilege = privilageRepository.save(new Privilege("READ_PROFILE")); 36 | role.getPrivileges().add(privilege); 37 | 38 | user.getRoles().add(role); 39 | user.setPassword(myBCryptPasswordEncoder.encode(user.getPassword())); 40 | userRepository.save(user); 41 | } 42 | 43 | public void createAdmin(User user) { 44 | Role role = roleRepository.findByName("ADMIN"); 45 | if (role == null) 46 | roleRepository.save(Role.valueOf("ADMIN")); 47 | Privilege privilege = privilageRepository.findByAuthority("EDIT_PROFILE"); 48 | if (privilege == null) 49 | privilege = privilageRepository.save(new Privilege("EDIT_PROFILE")); 50 | role.getPrivileges().add(privilege); 51 | privilege = privilageRepository.findByAuthority("READ_PROFILE"); 52 | if (privilege == null) 53 | privilege = privilageRepository.save(new Privilege("READ_PROFILE")); 54 | role.getPrivileges().add(privilege); 55 | privilege = privilageRepository.findByAuthority("DELETE_PROFILE"); 56 | if (privilege == null) 57 | privilege = privilageRepository.save(new Privilege("DELETE_PROFILE")); 58 | role.getPrivileges().add(privilege); 59 | user.getRoles().add(role); 60 | user.setPassword(myBCryptPasswordEncoder.encode(user.getPassword())); 61 | userRepository.save(user); 62 | } 63 | 64 | public void deleteAll() { 65 | userRepository.deleteAll(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8081 2 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 3 | spring.datasource.password=mysql 4 | spring.datasource.username=root 5 | spring.datasource.url=jdbc:mysql://localhost:3306/banque?serverTimezone=UTC 6 | spring.jpa.hibernate.ddl-auto=update 7 | springbootwebfluxjjwt.jjwt.secret=ThisIsSecretForJWTHS512SignatureAlgorithmThatMUSTHave512bitsKeySize 8 | springbootwebfluxjjwt.jjwt.expiration=600000 9 | springbootwebfluxjjwt.password.encoder.secret=mysecret 10 | springbootwebfluxjjwt.password.encoder.iteration=33 11 | springbootwebfluxjjwt.password.encoder.keylength=256 12 | -------------------------------------------------------------------------------- /src/test/java/com/SpringBootWebJwtApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringBootWebJwtApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------