рд╕рд▓рд╛рдо, рджреЛрд╕реНрддреЛрдВ! рдХрд▓ рдкрд╛рдареНрдпрдХреНрд░рдо
"рдбреЗрд╡рд▓рдкрд░ рдСрди рд╕реНрдкреНрд░рд┐рдВрдЧ рдлреНрд░реЗрдорд╡рд░реНрдХ" рдХреЗ рдирдП рдзрд╛рдЧреЗ рдореЗрдВ рдкрд╣рд▓реА рдХрдХреНрд╖рд╛рдПрдВ рд╢реБрд░реВ рдХрд░реЗрдЧрд╛ред рдЗрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ, рд╣рдо рдкрд╛рд░рдВрдкрд░рд┐рдХ рд░реВрдк рд╕реЗ рд╡рд┐рд╖рдп рдкрд░ рдЙрдкрдпреЛрдЧреА рд╕рд╛рдордЧреНрд░реА рд╕рд╛рдЭрд╛ рдХрд░рддреЗ рд╣реИрдВред

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рд╡рд╕рдВрдд рдмреВрдЯ рдФрд░ рд╡рд╕рдВрдд рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ OAuth2 рдФрд░ JWT рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВрдЧреЗред
рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕рд░реНрд╡рд░
рд╡реЗрдм API рд╕реБрд░рдХреНрд╖рд╛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдореЗрдВ рдПрдХ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕рд░реНрд╡рд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдШрдЯрдХ рд╣реИред рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕рд░реНрд╡рд░ рдПрдХ рдПрдХрд▓ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдмрд┐рдВрджреБ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдФрд░ HTTP рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдХреЛ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рд╕рдВрд╕рд╛рдзрди рд╕рд░реНрд╡рд░
рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕рд░реНрд╡рд░ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд░реНрд╡рд░ рдХреЗ HTTP рдПрдВрдбрдкреЙрдЗрдВрдЯ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХреНрд╕реЗрд╕ рдЯреЛрдХрди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдПрдХ рд╕рдВрд╕рд╛рдзрди рд╕рд░реНрд╡рд░ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИ рдЬрд┐рд╕рдореЗрдВ HTTP рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ, рд╕реНрдерд┐рд░ рд╕рдВрд╕рд╛рдзрди рдФрд░ рдЧрддрд┐рд╢реАрд▓ рд╡реЗрдм рдкреЗрдЬ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред
OAuth2
OAuth2 рдПрдХ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╣реИ рдЬреЛ рдХреНрд▓рд╛рдЗрдВрдЯ (рддреГрддреАрдп рдкрдХреНрд╖) рдХреЛ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред OAuth2 рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдиреБрджрд╛рди рдкреНрд░рдХрд╛рд░ (рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЛрдб), рдХреНрд▓рд╛рдЗрдВрдЯ рдЖрдИрдбреА рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рд░рд╣рд╕реНрдп рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ред
JWT рдЯреЛрдХрди
рдПрдХ JWT рдЯреЛрдХрди рдПрдХ JSON рд╡реЗрдм рдЯреЛрдХрди рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рджреЛ рдкрдХреНрд╖реЛрдВ рдХреЗ рдмреАрдЪ рд╕реБрд░рдХреНрд╖рд┐рдд рдкрд╣рдЪрд╛рди рд╕реВрдЪрдирд╛ (рджрд╛рд╡реЛрдВ) рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдк JWT tokens рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдЬрд╛рдирдХрд╛рд░реА
www.jwt.io рдкрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╣рдо JWT рдЯреЛрдХрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ OAuth2 рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕рд░реНрд╡рд░ рдФрд░ рдПрдХ рд╕рдВрд╕рд╛рдзрди рд╕рд░реНрд╡рд░ рд╢рд╛рдорд┐рд▓ рд╣реЛрдЧрд╛ред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЕрдкрдиреА рдмрд┐рд▓реНрдб рдлрд╝рд╛рдЗрд▓ рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред
Maven рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛
pom.xml
рдореЗрдВ рдирд┐рдореНрди рдирд┐рд░реНрднрд░рддрд╛рдПрдБ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>
рдЕрдиреБрд╡рд╛рджрдХ рдХрд╛ рдиреЛрдЯ - 9 рд╡рд░реНрд╖ рд╕реЗ рдЕрдзрд┐рдХ рдкреБрд░рд╛рдиреЗ рдЬрд╛рд╡рд╛ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рднреА рдЬреЛрдбрд╝рдиреА рд╣реЛрдВрдЧреА: <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.2.11</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.2.11</version> </dependency>
рдЧреНрд░реЗрдбрд▓ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд┐рдореНрди рдирд┐рд░реНрднрд░рддрд╛рдПрдБ
build.gradle
рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред
compile('org.springframework.boot:spring-boot-starter-security') compile('org.springframework.boot:spring-boot-starter-web') testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.springframework.security:spring-security-test') compile("org.springframework.security.oauth:spring-security-oauth2") compile('org.springframework.security:spring-security-jwt') compile("org.springframework.boot:spring-boot-starter-jdbc") compile("com.h2database:h2:1.4.191")
рдЬрд╣рд╛рдВ,
- рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рд╕реНрдЯрд╛рд░реНрдЯрд░ рд╕реБрд░рдХреНрд╖рд╛ - рд╕реНрдкреНрд░рд┐рдВрдЧ рд╕реБрд░рдХреНрд╖рд╛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ
- рд╕реНрдкреНрд░рд┐рдВрдЧ рд╕реБрд░рдХреНрд╖рд╛ OAuth2 - рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕рд░реНрд╡рд░ рдФрд░ рд╕рдВрд╕рд╛рдзрди рд╕рд░реНрд╡рд░ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП OAUTH2 рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
- рд╕реНрдкреНрд░рд┐рдВрдЧ рд╕рд┐рдХреНрдпреЛрд░рд┐рдЯреА JWT - JWT рдЯреЛрдХрди рдЬрдирд░реЗрдЯ рдХрд░рддрд╛ рд╣реИ
- рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рд╕реНрдЯрд╛рд░реНрдЯрд░ JDBC - рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рдмреЗрд╕ рдПрдХреНрд╕реЗрд╕ред
- рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рд╕реНрдЯрд╛рд░реНрдЯрд░ рд╡реЗрдм - HTTP рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
- H2 рдбреЗрдЯрд╛рдмреЗрд╕ - рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдФрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред
рдкреВрд░реНрдг
pom.xml
рдлрд╝рд╛рдЗрд▓
pom.xml
рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
<?xml version = "1.0" encoding = "UTF-8"?> <project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tutorialspoint</groupId> <artifactId>websecurityapp</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>websecurityapp</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Gradle тАФ build.gradle
buildscript { ext { springBootVersion = '1.5.9.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' group = 'com.tutorialspoint' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-security') compile('org.springframework.boot:spring-boot-starter-web') testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.springframework.security:spring-security-test') compile("org.springframework.security.oauth:spring-security-oauth2") compile('org.springframework.security:spring-security-jwt') compile("org.springframework.boot:spring-boot-starter-jdbc") compile("com.h2database:h2:1.4.191") }
рдЕрдм, рдореБрдЦреНрдп рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдореЗрдВ
@EnableAuthorizationServer
рдФрд░
@EnableResourceServer
рдПрдиреЛрдЯреЗрд╢рди рдЬреЛрдбрд╝реЗрдВ, рддрд╛рдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕рд░реНрд╡рд░ рдФрд░ рд╕рдВрд╕рд╛рдзрди рд╕рд░реНрд╡рд░ рджреЛрдиреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░реЗред
JWT рдЯреЛрдХрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдкреНрд░рд┐рдВрдЧ рд╕рд┐рдХреНрдпреЛрд░рд┐рдЯреА-рд╕рдВрд░рдХреНрд╖рд┐рдд рдПрдкреАрдЖрдИ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдзрд╛рд░рдг HTTP рдПрдВрдбрдкреЙрдЗрдВрдЯ (/ рдЙрддреНрдкрд╛рдж) рднреА рдЬреЛрдбрд╝реЗрдВред
package com.tutorialspoint.websecurityapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @EnableAuthorizationServer @EnableResourceServer @RestController public class WebsecurityappApplication { public static void main(String[] args) { SpringApplication.run(WebsecurityappApplication.class, args); } @RequestMapping(value = "/products") public String getProductName() { return "Honey"; } }
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП POJO рд╡рд░реНрдЧ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВред
package com.tutorialspoint.websecurityapp; import java.util.ArrayList; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; public class UserEntity { private String username; private String password; private Collection<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>(); public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Collection<GrantedAuthority> getGrantedAuthoritiesList() { return grantedAuthoritiesList; } public void setGrantedAuthoritiesList(Collection<GrantedAuthority> grantedAuthoritiesList) { this.grantedAuthoritiesList = grantedAuthoritiesList; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
рдЗрд╕рдХреЗ рдмрд╛рдж, рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХреЗ рд▓рд┐рдП, CustomUser рд╡рд░реНрдЧ рдЬреЛрдбрд╝реЗрдВ, рдЬреЛ org.springframework.security.core.userdetails.User рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИред
package com.tutorialspoint.websecurityapp; import org.springframework.security.core.userdetails.User; public class CustomUser extends User { private static final long serialVersionUID = 1L; public CustomUser(UserEntity user) { super(user.getUsername(), user.getPassword(), user.getGrantedAuthoritiesList()); } }
рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ ROLE_SYSTEMADMIN рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ
@Repository-
рдмрдирд╛рдПрдБред рдЗрд╕ рдХрдХреНрд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ
CustomDetailsService
рдореЗрдВ рднреА рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
package com.tutorialspoint.websecurityapp; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Repository; @Repository public class OAuthDao { @Autowired private JdbcTemplate jdbcTemplate; public UserEntity getUserDetails(String username) { Collection<GrantedAuthority> grantedAuthoritiesList = new ArrayList<>(); String userSQLQuery = "SELECT * FROM USERS WHERE USERNAME=?"; List<UserEntity> list = jdbcTemplate.query(userSQLQuery, new String[] { username }, (ResultSet rs, int rowNum) -> { UserEntity user = new UserEntity(); user.setUsername(username); user.setPassword(rs.getString("PASSWORD")); return user; }); if (list.size() > 0) { GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_SYSTEMADMIN"); grantedAuthoritiesList.add(grantedAuthority); list.get(0).setGrantedAuthoritiesList(grantedAuthoritiesList); return list.get(0); } return null; } }
DAO рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЕрдкрдирд╛
UserDetailsService
рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ
UserDetailsService
рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
package com.tutorialspoint.websecurityapp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; @Service public class CustomDetailsService implements UserDetailsService { @Autowired OAuthDao oauthDao; @Override public CustomUser loadUserByUsername(final String username) throws UsernameNotFoundException { UserEntity userEntity = null; try { userEntity = oauthDao.getUserDetails(username); CustomUser customUser = new CustomUser(userEntity); return customUser; } catch (Exception e) { e.printStackTrace(); throw new UsernameNotFoundException("User " + username + " was not found in the database"); } } }
рдЗрд╕рдХреЗ рдмрд╛рдж,
Web Security
рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
@onfiguration-
рдмрдирд╛рдПрдВред рдкрд╛рд╕рд╡рд░реНрдб рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ (
BCryptPasswordEncoder
) рдФрд░ рдЗрд╕рдореЗрдВ рдореМрдЬреВрдж
AuthenticationManager
BCryptPasswordEncoder
рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВред
рдЗрд╕
SecurityConfiguration
рд╡рд░реНрдЧ рдХреЛ
WebSecurityConfigurerAdapter
рд╡рд░реНрдЧ рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
package com.tutorialspoint.websecurityapp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private CustomDetailsService customDetailsService; @Bean public PasswordEncoder encoder() { return new BCryptPasswordEncoder(); } @Override @Autowired protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customDetailsService).passwordEncoder(encoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated().and().sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.NEVER); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring(); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } }
рдЕрдм OAuth2 рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд░реНрдЧ рдЬреЛрдбрд╝реЗрдВред рдЗрд╕рдореЗрдВ, рдЯреЛрдХрди рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдФрд░ рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рдХреНрд▓рд╛рдЗрдВрдЯ рдЖрдИрдбреА, рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реАрдХреНрд░реЗрдЯ, JwtAccessTokenConverter, рдирд┐рдЬреА рдФрд░ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ рдФрд░ рдорд╛рдиреНрдп рдЯреЛрдХрди рд╕реНрдХреЛрдк рдХреЗ рд▓рд┐рдП
ClientDetailsServiceConfigurer
рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред
package com.tutorialspoint.websecurityapp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; @Configuration public class OAuth2Config extends AuthorizationServerConfigurerAdapter { private String clientid = "tutorialspoint"; private String clientSecret = "my-secret-key"; private String privateKey = "private key"; private String publicKey = "public key"; @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Bean public JwtAccessTokenConverter tokenEnhancer() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(privateKey); converter.setVerifierKey(publicKey); return converter; } @Bean public JwtTokenStore tokenStore() { return new JwtTokenStore(tokenEnhancer()); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore()) .accessTokenConverter(tokenEnhancer()); } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()"); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient(clientid).secret(clientSecret).scopes("read", "write") .authorizedGrantTypes("password", "refresh_token").accessTokenValiditySeconds(20000) .refreshTokenValiditySeconds(20000); } }
рдЕрдм рдирд┐рдЬреА рдФрд░ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХреБрдВрдЬреА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддрд╛ рд╣реИред
рдПрдХ рдирд┐рдЬреА рдХреБрдВрдЬреА рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ -
openssl genrsa -out jwt.pem 2048 openssl rsa -in jwt.pem
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХреБрдВрдЬреА рдХреЗ рд▓рд┐рдП -
openssl rsa -in jwt.pem -pubout
рд╕рдВрд╕реНрдХрд░рдг 1.5 рд╕реЗ рдкреБрд░рд╛рдиреЗ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрди рд╕рдВрдкрддреНрддрд┐ рдХреЛ
application.properties
рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ (OAuth2 рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреНрд░рдо рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП)ред
security.oauth2.resource.filter-order=3
рдпрджрд┐ рдЖрдк рдПрдХ YAML рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдирд┐рдореНрди рдЬреЛрдбрд╝реЗрдВред
security: oauth2: resource: filter-order: 3
рдЕрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ H2 рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
src/main/resources/directory
data.sql
рдореЗрдВ
classpath
рдореЗрдВ
schema.sql
рдФрд░
data.sql
рдмрдирд╛рдПрдВред
schema.sql
ред
schema.sql
рдлрд╝рд╛рдЗрд▓ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИ:
CREATE TABLE USERS (ID INT PRIMARY KEY, USERNAME VARCHAR(45), PASSWORD VARCHAR(60)); data.sql: INSERT INTO USERS (ID, USERNAME,PASSWORD) VALUES ( 1, 'tutorialspoint@gmail.com','$2a$08$fL7u5xcvsZl78su29x1ti.dxI.9rYO8t0q5wk2ROJ.1cdR53bmaVG'); INSERT INTO USERS (ID, USERNAME,PASSWORD) VALUES ( 2, 'myemail@gmail.com','$2a$08$fL7u5xcvsZl78su29x1ti.dxI.9rYO8t0q5wk2ROJ.1cdR53bmaVG');
рдиреЛрдЯ - рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкрд╛рд╕рд╡рд░реНрдб Bcrypt рдПрдирдХреЛрдбрд░ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЖрдк рдПрдХ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп JAR рдлрд╝рд╛рдЗрд▓ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдирд┐рдореНрди Maven рдпрд╛ Gradle рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдорд╛рд╡реЗрди рдХреЗ рд▓рд┐рдП, рдЖрдк рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ -
mvn clean install
"рдирд┐рд░реНрдорд╛рдг рд╕рдлрд▓рддрд╛" рдХреЗ рдмрд╛рдж рдЖрдк
target
рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдЬрд╛рд░ рдлрд╛рдЗрд▓реЗрдВ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдЧреНрд░реЗрдбрд▓ рдХреЗ рд▓рд┐рдП, рдЖрдк рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ -
gradle clean build
тАЬBUILD SUCCESSFULтАЭ рдХреЗ рдмрд╛рдж рдЖрдк JAR рдлрд╛рдЗрд▓реЛрдВ рдХреЛ
build/libs
рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдореЗрдВ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдЕрдм рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде JAR рдлрд╝рд╛рдЗрд▓ рдЪрд▓рд╛рдПрдБ -
java тАУjar <
JARFILE
>
рдкреЛрд░реНрдЯ 8080 рдкрд░ рдЯреЙрдордХреИрдЯ рдореЗрдВ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рдиред

рдЕрдм OAUTH2 рдЯреЛрдХрди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП POSTMAN рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ POST рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдВред
http://localhost:8080/oauth/token
рдЕрдм рдЕрдиреБрд░реЛрдз рд╣реЗрдбрд░ рдЬреЛрдбрд╝реЗрдВ -
- рдкреНрд░рд╛рдзрд┐рдХрд░рдг - рдЖрдкрдХреЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдЖрдИрдбреА рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рд░рд╣рд╕реНрдп рдХреЗ рд╕рд╛рде рдмреБрдирд┐рдпрд╛рджреАред
- рд╕рд╛рдордЧреНрд░реА-рдкреНрд░рдХрд╛рд░ - рдЖрд╡реЗрджрди / x-www-form-urlencoded

рдФрд░ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ -
- рдЕрдиреБрджрд╛рди_рдкреНрд░рдХрд╛рд░ = рдкрд╛рд╕рд╡рд░реНрдб
- рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо = рдЖрдкрдХрд╛ рдирд╛рдо
- рдкрд╛рд╕рд╡рд░реНрдб = рдЖрдкрдХрд╛ рдкрд╛рд╕рд╡рд░реНрдб

рдЕрдм рдЪрд▓рд╛рдПрдВ рдФрд░ рджрд┐рдЦрд╛рдП рдЧрдП рдЕрдиреБрд╕рд╛рд░
access_token
рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред

рдЕрдм рд╣реЗрдбрд░ рдореЗрдВ рдмрд┐рдпрд░рд░ рдЯреЛрдХрди рдХреЗ рд╕рд╛рде рд░рд┐рд╕реЛрд░реНрд╕ рд╕рд░реНрд╡рд░ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд░реЗрдВред

рд╣рдореЗрдВ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЕрдиреБрд╕рд╛рд░ рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓рддрд╛ рд╣реИред

рд╣рдо рдЖрдкрдХреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рд╣рдо рдЖрдкрдХреЛ рдпрд╣ рднреА рд╕реВрдЪрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ 31 рдордИ рддрдХ рдЖрдк рдПрдХ рд╡рд┐рд╢реЗрд╖ рдореВрд▓реНрдп рдкрд░
рдкрд╛рдареНрдпрдХреНрд░рдо рдореЗрдВ
рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред