├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── authentication-provider
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── livelessons
│ │ │ ├── custom
│ │ │ └── AuthenticationProviderApplication.java
│ │ │ └── ldap
│ │ │ └── LdapAuthenticationApplication.java
│ └── resources
│ │ ├── application-ldap.properties
│ │ └── test-server.ldif
│ └── test
│ └── java
│ └── livelessons
│ ├── custom
│ ├── AtlassianCrowdAuthenticationProviderTest.java
│ └── AuthenticationProviderApplicationTest.java
│ └── ldap
│ └── LdapAuthenticationApplicationTest.java
├── login
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── livelessons
│ │ │ └── LoginApplication.java
│ └── resources
│ │ ├── application.properties
│ │ └── templates
│ │ ├── hidden.html
│ │ ├── layout.html
│ │ ├── login.html
│ │ └── logout.html
│ └── test
│ ├── java
│ └── livelessons
│ │ ├── LoginApplicationTests.java
│ │ └── webdriver
│ │ ├── HiddenPage.java
│ │ └── LoginPage.java
│ └── resources
│ └── logback-test.xml
├── password-migration
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── passwordmigration
│ │ │ ├── CustomAuthenticationApplication.java
│ │ │ ├── CustomSecurityConfiguration.java
│ │ │ ├── CustomUserDetails.java
│ │ │ ├── CustomUserDetailsService.java
│ │ │ └── GreetingRestController.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── passwordmigration
│ └── PasswordMigrationApplicationTests.java
├── pom.xml
├── studio
├── auditing
│ ├── .gitignore
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── customauthentication
│ │ │ │ └── CustomAuthenticationApplication.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── customauthentication
│ │ └── CustomAuthenticationApplicationTests.java
├── custom-authentication
│ ├── .gitignore
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── customauthentication
│ │ │ │ └── CustomAuthenticationApplication.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── customauthentication
│ │ └── CustomAuthenticationApplicationTests.java
├── inmemory
│ ├── .gitignore
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── inmemory
│ │ │ │ └── InmemoryApplication.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── inmemory
│ │ └── InmemoryApplicationTests.java
├── jdbc
│ ├── .gitignore
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── jdbc
│ │ │ │ └── JdbcApplication.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── schema.sql
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── jdbc
│ │ └── JdbcApplicationTests.java
├── ldap
│ ├── .gitignore
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── ldap
│ │ │ │ └── LdapApplication.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── test-server.ldif
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── ldap
│ │ └── LdapApplicationTests.java
├── login
│ ├── .gitignore
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── login
│ │ │ │ └── LoginApplication.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── templates
│ │ │ ├── hidden.html
│ │ │ ├── layout.html
│ │ │ ├── login.html
│ │ │ └── logout.html
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── login
│ │ └── LoginApplicationTests.java
└── password-encoding-and-migration
│ ├── .gitignore
│ ├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── customauthentication
│ │ │ └── CustomAuthenticationApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── customauthentication
│ └── CustomAuthenticationApplicationTests.java
├── user-details
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── livelessons
│ │ │ └── AuthenticationApplication.java
│ └── resources
│ │ ├── application.properties
│ │ └── schema.sql
│ └── test
│ └── java
│ └── livelessons
│ ├── JdbcUserDetailsServiceTest.java
│ ├── MemoryUserDetailsServiceTest.java
│ ├── SimpleUserDetailsServiceTest.java
│ └── UserDetailsServiceTestBaseClass.java
├── xauth-app
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── livelessons
│ │ │ └── custom
│ │ │ └── CustomApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── livelessons
│ └── custom
│ └── GreetingsRestControllerTest.java
└── xauth
├── pom.xml
└── src
└── main
├── java
└── livelessons
│ └── xauth
│ ├── TokenUtils.java
│ ├── XAuthAutoConfiguration.java
│ ├── XAuthConfiguration.java
│ ├── XAuthDslConfigurer.java
│ ├── XAuthTokenFilter.java
│ └── XAuthTokenRestController.java
└── resources
├── META-INF
└── spring.factories
└── application.properties
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | .idea
3 | *.iml
4 | pom.xml.tag
5 | pom.xml.releaseBackup
6 | pom.xml.versionsBackup
7 | pom.xml.next
8 | release.properties
9 | dependency-reduced-pom.xml
10 | buildNumber.properties
11 | .mvn/timing.properties
12 |
13 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
14 | !/.mvn/wrapper/maven-wrapper.jar
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 |
3 | jdk:
4 | - oraclejdk8
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Authentication
2 | - problems with HTTP basic requires validation on every request. ur passing credentials every request! bad. more surface area. plus if u r encoding ur passwords properly it should take half a second to a second. which means this is slow. in authentication world u'd normally exchange long term credentials for a short term credentials. it takes longer to rotate username/password than a short term credential. also, people often reuse user/passwords so if its compromised then it has a larger impact than a short term creential which is secure random generated. SO, use some other mechanism. u use http basic to transport user/pw and exchange it for short term credentials. this is what youre doing in a form login. the other bad thing about http basic in a browser is that u can't logout. the only way to get out of the lopo is to close the whole browser. so, well use a proper authentication mechanism like a form login.
3 |
4 | - why user details? its har to get password encoding correct. u want to make sure u get password encoding correct. u want to make sure u get all the details correct. if the user doesnt exist we dont want to reveal the user that is missing. there are side channel attacks like figuring out if the user exists based on how long it takes to process the request. if a user does exist, given what we know about password encoding, it should take something like .5 -1s. but naive code (from the pOV of security) might take much less time for somebody who DOESNT exist, because there's no password to validate. the correct performance engineering approach here, to return quickly, would be the wrong thing to do from a security pov. if the user doesnt exist, Spring Security has a dummy password that we always compare against. also, we want to avoid session fixation attacks by changing the JSESSIONID on login (when we promote a regular http session to an authenticated session). we also need to rotate the csrf token.
5 |
6 | - LDAP: dn = domain name (a hierarchy to find the current user, or anythign in LDAP). LDAP is a tree structure. `uid={0},ou=people` says find a UID leaf under the people branch. user info is in one tree, and groups (roles/autorities) are stored in another. so we must psecify both queries. `ou=groups` does that. `ldap://localhost:8389/dc=springframework,dc=org` is the base URL for both groups and users. eg: `dc=springframework,dc=org,ou=people,uid=....` there are two type sof auth in ldap: BIND authentication. BIND is that whateve the user types for user and password u try to LDAP bind by presenting user/pw to directory an i tells u if the user/pw is correct. the other type, LDAP search, is password comparison wherein we submit a query, get results, an compare PW in spring security client java code. So, auth happens in LDAP bind on the LDAP server and auth happens in the spring security client in second type. the LDAP server usually has a password encoding approach. there are specific fields for passwords. as an app developer we reately have the ability to 'write' passwords to LDAP, omore often need to read from LDAP that exists for other purporses. its been installed by the organiation and we have to reuse it. so, while we could a) side step the password field and write passwords that we encode into some other field and b) mae spring security aware of this change c) read the passwords and compare them in the client code, this is impractical. so we use things like `LdapShaPasswordEncoder` , which you can see is deprecated but NOT going anywhere. its a warning!
7 |
8 | https://stackoverflow.com/questions/18756688/what-are-cn-ou-dc-in-an-ldap-search/18756876
9 | CN = Common Name
10 | OU = Organizational Unit
11 | DC = Domain Component
12 | These are all parts of the X.500 Directory Specification, which defines nodes in a LDAP directory.
13 |
14 | You can also read up on LDAP data Interchange Format (LDIF), which is an alternate format.
15 |
16 | You read it from right to left, the right-most component is the root of the tree, and the left most component is the node (or leaf) you want to reach.
17 |
18 | Each = pair is a search criteria.
19 |
20 | With your example query
21 |
22 | ("CN=Dev-India,OU=Distribution Groups,DC=gp,DC=gl,DC=google,DC=com");
23 | In effect the query is:
24 |
25 |
26 |
27 |
28 | 1. this is plain text. use NoOpPasswordEncoder.getInstance() ;
29 | 2. in order to take advantage of the new password encode in Sing security u need to migrate existing passwords.
30 | 3. if u are using plaint text that amounts to prefixing it whatever the appropirate prefix.
31 | 4. now replace NooOPWEncoder w/ DelegatingPWencoder
32 | 5. now imagine u have a signup page and the new user signs up and uses BCrypt. Use the DelegatingPWEncoder to encode new strings. the default is bcrypt.
33 | 6. NEW! spring security UDS supports password migration through the UserDetailsPasswordService. Out of the box only InMemoryUDM supports this. the idea is simple. we want them to login and SS
34 | and ideally to change their password. SS will automatically check if the old password was stored in a insecure way and migrate to brcypt by invoking our UserDetailsPasswordService.
35 | All fo that logic is in the DaoAuthentiationProvider. It scostly to upgrade the encoding so we dont do this unless we need to
36 | But ur auth SHOULD support it. so the business/marketing could be any of a number of things. "weve changed terms of service. login." or "its been a month, password expired." or
37 | "we want to proactively protect u. taking additional measures."
38 | 7. there were two different PasswordEncoders in SS 4.2
39 | 8. if you are using the old password encoders u should see the migration javadocs in org.springframework.security.crypto.password.MessageDigestPasswordEncoder.
40 |
41 |
42 | Custom Authentication: use a REST controller to handle login by setting the SecurityContext...*.
43 |
--------------------------------------------------------------------------------
/authentication-provider/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | authentication-provider
7 |
8 | livelessons
9 | authentication
10 | 0.0.1-SNAPSHOT
11 | ..
12 |
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-security
17 |
18 |
19 | org.springframework.boot
20 | spring-boot-starter-web
21 |
22 |
23 | org.springframework.ldap
24 | spring-ldap-core
25 |
26 |
27 | org.springframework.security
28 | spring-security-ldap
29 |
30 |
31 | com.unboundid
32 | unboundid-ldapsdk
33 |
34 |
35 | org.projectlombok
36 | lombok
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-test
41 | test
42 |
43 |
44 | org.springframework.security
45 | spring-security-test
46 | test
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/authentication-provider/src/main/java/livelessons/custom/AuthenticationProviderApplication.java:
--------------------------------------------------------------------------------
1 | package livelessons.custom;
2 |
3 | import org.apache.commons.logging.Log;
4 | import org.apache.commons.logging.LogFactory;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.security.authentication.AuthenticationProvider;
10 | import org.springframework.security.authentication.BadCredentialsException;
11 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
12 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
13 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
14 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
15 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
16 | import org.springframework.security.core.Authentication;
17 | import org.springframework.security.core.AuthenticationException;
18 | import org.springframework.security.core.authority.AuthorityUtils;
19 | import org.springframework.stereotype.Component;
20 | import org.springframework.web.bind.annotation.GetMapping;
21 | import org.springframework.web.bind.annotation.RestController;
22 |
23 | import java.security.Principal;
24 |
25 | @SpringBootApplication
26 | public class AuthenticationProviderApplication {
27 |
28 | public static void main(String args[]) {
29 | SpringApplication.run(AuthenticationProviderApplication.class, args);
30 | }
31 |
32 | @Configuration
33 | @EnableWebSecurity
34 | public static class BasicAuthorizationConfig extends WebSecurityConfigurerAdapter {
35 |
36 | private final AtlassianCrowdAuthenticationProvider authenticationProvider;
37 |
38 | public BasicAuthorizationConfig(
39 | AtlassianCrowdAuthenticationProvider authenticationProvider) {
40 | this.authenticationProvider = authenticationProvider;
41 | }
42 |
43 | @Override
44 | protected void configure(AuthenticationManagerBuilder auth) throws Exception {
45 | auth.authenticationProvider(this.authenticationProvider);
46 | }
47 |
48 | @Override
49 | protected void configure(HttpSecurity http) throws Exception {
50 | http.csrf().and().httpBasic().and().authorizeRequests().anyRequest()
51 | .authenticated();
52 | }
53 |
54 | }
55 |
56 | }
57 |
58 | @RestController
59 | class GreetingsRestController {
60 |
61 | @GetMapping("/greet")
62 | String greet(Principal p) {
63 | return "hello, " + p.getName() + "!";
64 | }
65 |
66 | }
67 |
68 | @Component
69 | class AtlassianCrowdAuthenticationProvider implements AuthenticationProvider {
70 |
71 | private final Log log = LogFactory.getLog(getClass());
72 |
73 | // visible for testing.
74 | final String hardcodedUsername, hardcodedPassword;
75 |
76 | AtlassianCrowdAuthenticationProvider(@Value("${username:user}") String usr,
77 | @Value("${password:pw}") String pw) {
78 | this.hardcodedUsername = usr;
79 | this.hardcodedPassword = pw;
80 | }
81 |
82 | @Override
83 | public Authentication authenticate(Authentication authentication)
84 | throws AuthenticationException {
85 |
86 | String username = authentication.getName();
87 | String password = authentication.getCredentials().toString();
88 |
89 | if (isValid(username, password)) {
90 | return new UsernamePasswordAuthenticationToken(username, password,
91 | AuthorityUtils.createAuthorityList("USER"));
92 | }
93 |
94 | throw new BadCredentialsException(
95 | "couldn't authenticate (" + authentication + ")");
96 | }
97 |
98 | private boolean isValid(String username, String password) {
99 | return (username.equalsIgnoreCase(this.hardcodedUsername)
100 | && password.equalsIgnoreCase(this.hardcodedPassword));
101 | }
102 |
103 | @Override
104 | public boolean supports(Class> authentication) {
105 | return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/authentication-provider/src/main/java/livelessons/ldap/LdapAuthenticationApplication.java:
--------------------------------------------------------------------------------
1 | package livelessons.ldap;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.context.annotation.Profile;
7 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
10 | import org.springframework.security.crypto.password.LdapShaPasswordEncoder;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 | import org.springframework.web.bind.annotation.RestController;
13 |
14 | import java.security.Principal;
15 |
16 | @SpringBootApplication
17 | public class LdapAuthenticationApplication {
18 |
19 | public static void main(String args[]) {
20 | SpringApplication.run(LdapAuthenticationApplication.class, args);
21 | }
22 |
23 | /**
24 | * @see What is
26 | * LDAP
27 | */
28 | @Profile("ldap")
29 | @Configuration
30 | public static class LdapConfiguration extends WebSecurityConfigurerAdapter {
31 |
32 | @Override
33 | protected void configure(AuthenticationManagerBuilder auth) throws Exception {
34 |
35 | auth.ldapAuthentication().userDnPatterns("uid={0},ou=people")
36 | .groupSearchBase("ou=groups").contextSource()
37 | .url("ldap://localhost:8389/dc=springframework,dc=org").and()
38 | .passwordCompare().passwordEncoder(new LdapShaPasswordEncoder())
39 | .passwordAttribute("userPassword");
40 | }
41 |
42 | @Override
43 | protected void configure(HttpSecurity http) throws Exception {
44 | http.csrf().and().httpBasic().and().authorizeRequests().anyRequest()
45 | .authenticated();
46 | }
47 |
48 | }
49 |
50 | }
51 |
52 | @RestController
53 | class GreetingsRestController {
54 |
55 | @GetMapping("/greet")
56 | String greet(Principal p) {
57 | return "hello, " + p.getName() + "!";
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/authentication-provider/src/main/resources/application-ldap.properties:
--------------------------------------------------------------------------------
1 | spring.ldap.embedded.ldif=classpath:test-server.ldif
2 | spring.ldap.embedded.base-dn=dc=springframework,dc=org
3 | spring.ldap.embedded.port=8389
--------------------------------------------------------------------------------
/authentication-provider/src/main/resources/test-server.ldif:
--------------------------------------------------------------------------------
1 | dn: dc=springframework,dc=org
2 | objectclass: top
3 | objectclass: domain
4 | objectclass: extensibleObject
5 | dc: springframework
6 |
7 | dn: ou=groups,dc=springframework,dc=org
8 | objectclass: top
9 | objectclass: organizationalUnit
10 | ou: groups
11 |
12 | dn: ou=subgroups,ou=groups,dc=springframework,dc=org
13 | objectclass: top
14 | objectclass: organizationalUnit
15 | ou: subgroups
16 |
17 | dn: ou=people,dc=springframework,dc=org
18 | objectclass: top
19 | objectclass: organizationalUnit
20 | ou: people
21 |
22 | dn: ou=space cadets,dc=springframework,dc=org
23 | objectclass: top
24 | objectclass: organizationalUnit
25 | ou: space cadets
26 |
27 | dn: ou=\"quoted people\",dc=springframework,dc=org
28 | objectclass: top
29 | objectclass: organizationalUnit
30 | ou: "quoted people"
31 |
32 | dn: ou=otherpeople,dc=springframework,dc=org
33 | objectclass: top
34 | objectclass: organizationalUnit
35 | ou: otherpeople
36 |
37 | dn: uid=ben,ou=people,dc=springframework,dc=org
38 | objectclass: top
39 | objectclass: person
40 | objectclass: organizationalPerson
41 | objectclass: inetOrgPerson
42 | cn: Ben Alex
43 | sn: Alex
44 | uid: ben
45 | userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
46 |
47 | dn: uid=bob,ou=people,dc=springframework,dc=org
48 | objectclass: top
49 | objectclass: person
50 | objectclass: organizationalPerson
51 | objectclass: inetOrgPerson
52 | cn: Bob Hamilton
53 | sn: Hamilton
54 | uid: bob
55 | userPassword: bobspassword
56 |
57 | dn: uid=joe,ou=otherpeople,dc=springframework,dc=org
58 | objectclass: top
59 | objectclass: person
60 | objectclass: organizationalPerson
61 | objectclass: inetOrgPerson
62 | cn: Joe Smeth
63 | sn: Smeth
64 | uid: joe
65 | userPassword: joespassword
66 |
67 | dn: cn=mouse\, jerry,ou=people,dc=springframework,dc=org
68 | objectclass: top
69 | objectclass: person
70 | objectclass: organizationalPerson
71 | objectclass: inetOrgPerson
72 | cn: Mouse, Jerry
73 | sn: Mouse
74 | uid: jerry
75 | userPassword: jerryspassword
76 |
77 | dn: cn=slash/guy,ou=people,dc=springframework,dc=org
78 | objectclass: top
79 | objectclass: person
80 | objectclass: organizationalPerson
81 | objectclass: inetOrgPerson
82 | cn: slash/guy
83 | sn: Slash
84 | uid: slashguy
85 | userPassword: slashguyspassword
86 |
87 | dn: cn=quote\"guy,ou=\"quoted people\",dc=springframework,dc=org
88 | objectclass: top
89 | objectclass: person
90 | objectclass: organizationalPerson
91 | objectclass: inetOrgPerson
92 | cn: quote\"guy
93 | sn: Quote
94 | uid: quoteguy
95 | userPassword: quoteguyspassword
96 |
97 | dn: uid=space cadet,ou=space cadets,dc=springframework,dc=org
98 | objectclass: top
99 | objectclass: person
100 | objectclass: organizationalPerson
101 | objectclass: inetOrgPerson
102 | cn: Space Cadet
103 | sn: Cadet
104 | uid: space cadet
105 | userPassword: spacecadetspassword
106 |
107 | dn: cn=developers,ou=groups,dc=springframework,dc=org
108 | objectclass: top
109 | objectclass: groupOfUniqueNames
110 | cn: developers
111 | ou: developer
112 | uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
113 | uniqueMember: uid=bob,ou=people,dc=springframework,dc=org
114 |
115 | dn: cn=managers,ou=groups,dc=springframework,dc=org
116 | objectclass: top
117 | objectclass: groupOfUniqueNames
118 | cn: managers
119 | ou: manager
120 | uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
121 | uniqueMember: cn=mouse\, jerry,ou=people,dc=springframework,dc=org
122 |
123 | dn: cn=submanagers,ou=subgroups,ou=groups,dc=springframework,dc=org
124 | objectclass: top
125 | objectclass: groupOfUniqueNames
126 | cn: submanagers
127 | ou: submanager
128 | uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
129 |
--------------------------------------------------------------------------------
/authentication-provider/src/test/java/livelessons/custom/AtlassianCrowdAuthenticationProviderTest.java:
--------------------------------------------------------------------------------
1 | package livelessons.custom;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import org.springframework.security.authentication.BadCredentialsException;
6 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
7 | import org.springframework.security.authentication.jaas.JaasAuthenticationToken;
8 | import org.springframework.security.core.Authentication;
9 |
10 | public class AtlassianCrowdAuthenticationProviderTest {
11 |
12 | private final String username = "rob";
13 |
14 | private final String password = "b0r";
15 |
16 | private final AtlassianCrowdAuthenticationProvider provider = new AtlassianCrowdAuthenticationProvider(
17 | this.username, this.password);
18 |
19 | @Test
20 | public void authenticateSuccess() {
21 |
22 | UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
23 | username, password);
24 | Authentication authenticate = this.provider.authenticate(token);
25 | Assert.assertTrue("the authentication should be valid",
26 | authenticate.isAuthenticated());
27 | }
28 |
29 | @Test(expected = BadCredentialsException.class)
30 | public void authenticateFail() {
31 | UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
32 | "WR0NG", "N0P3");
33 | this.provider.authenticate(token);
34 | Assert.fail("this should fail");
35 | }
36 |
37 | @Test
38 | public void supports() {
39 | Assert.assertTrue(
40 | this.provider.supports(UsernamePasswordAuthenticationToken.class));
41 | Assert.assertTrue(this.provider.supports(JaasAuthenticationToken.class));
42 | Assert.assertFalse(this.provider.supports(RuntimeException.class));
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/authentication-provider/src/test/java/livelessons/custom/AuthenticationProviderApplicationTest.java:
--------------------------------------------------------------------------------
1 | package livelessons.custom;
2 |
3 | import org.apache.commons.logging.Log;
4 | import org.apache.commons.logging.LogFactory;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 | import org.junit.runner.RunWith;
8 | import org.springframework.beans.BeansException;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.beans.factory.config.BeanPostProcessor;
11 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
12 | import org.springframework.boot.test.context.SpringBootTest;
13 | import org.springframework.context.annotation.Bean;
14 | import org.springframework.context.annotation.Configuration;
15 | import org.springframework.http.HttpHeaders;
16 | import org.springframework.test.context.junit4.SpringRunner;
17 | import org.springframework.test.web.servlet.MockMvc;
18 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
19 | import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
20 |
21 | import java.nio.charset.StandardCharsets;
22 | import java.util.Base64;
23 |
24 | @SpringBootTest(classes = { AuthenticationProviderApplication.class,
25 | AuthenticationProviderApplicationTest.Replacer.class })
26 | @RunWith(SpringRunner.class)
27 | @AutoConfigureMockMvc
28 | public class AuthenticationProviderApplicationTest {
29 |
30 | private static final String USER = "USER", PW = "PW";
31 |
32 | @Configuration
33 | public static class Replacer {
34 |
35 | @Bean
36 | BeanPostProcessor beanPostProcessor() {
37 | return new BeanPostProcessor() {
38 |
39 | @Override
40 | public Object postProcessBeforeInitialization(Object bean,
41 | String beanName) throws BeansException {
42 | if (bean instanceof AtlassianCrowdAuthenticationProvider) {
43 | // want to replace it with one that we control for the test.
44 | return new AtlassianCrowdAuthenticationProvider(USER, PW);
45 | }
46 | else {
47 | return bean;
48 | }
49 | }
50 |
51 | @Override
52 | public Object postProcessAfterInitialization(Object bean, String beanName)
53 | throws BeansException {
54 | return bean;
55 | }
56 | };
57 | }
58 |
59 | }
60 |
61 | @Autowired
62 | private MockMvc mockMvc;
63 |
64 | private final Log log = LogFactory.getLog(getClass());
65 |
66 | @Autowired
67 | public void config(AtlassianCrowdAuthenticationProvider ap) throws Exception {
68 | this.log.info(String.format(
69 | "attempting to authenticate using username '%s' and password '%s'",
70 | ap.hardcodedUsername, ap.hardcodedPassword));
71 | }
72 |
73 | @Test
74 | public void login() throws Exception {
75 |
76 | String name = USER, pw = PW;
77 | this.mockMvc
78 | .perform(MockMvcRequestBuilders.get("/greet").header(
79 | HttpHeaders.AUTHORIZATION, basicAuthorizationHeader(name, pw)))
80 | .andExpect(MockMvcResultMatchers.status().isOk()).andExpect(result -> {
81 | String body = result.getResponse().getContentAsString();
82 | Assert.assertEquals(body, "hello, " + name + "!");
83 | });
84 | }
85 |
86 | private String basicAuthorizationHeader(String u, String p) {
87 | String auth = u + ':' + p;
88 | byte[] encoded = Base64.getEncoder()
89 | .encode(auth.getBytes(StandardCharsets.ISO_8859_1));
90 | return "Basic " + new String(encoded);
91 | }
92 |
93 | }
--------------------------------------------------------------------------------
/authentication-provider/src/test/java/livelessons/ldap/LdapAuthenticationApplicationTest.java:
--------------------------------------------------------------------------------
1 | package livelessons.ldap;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
8 | import org.springframework.boot.test.context.SpringBootTest;
9 | import org.springframework.http.HttpHeaders;
10 | import org.springframework.test.context.ActiveProfiles;
11 | import org.springframework.test.context.junit4.SpringRunner;
12 | import org.springframework.test.web.servlet.MockMvc;
13 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
14 | import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
15 |
16 | import java.nio.charset.StandardCharsets;
17 | import java.util.Base64;
18 |
19 | @SpringBootTest(classes = { LdapAuthenticationApplication.class })
20 | @RunWith(SpringRunner.class)
21 | @AutoConfigureMockMvc
22 | @ActiveProfiles("ldap")
23 | public class LdapAuthenticationApplicationTest {
24 |
25 | @Autowired
26 | private MockMvc mockMvc;
27 |
28 | @Test
29 | public void login() throws Exception {
30 | String name = "ben", pw = "benspassword";
31 | this.mockMvc
32 | .perform(MockMvcRequestBuilders.get("/greet").header(
33 | HttpHeaders.AUTHORIZATION, basicAuthorizationHeader(name, pw)))
34 | .andExpect(MockMvcResultMatchers.status().isOk()).andExpect(result -> {
35 | String body = result.getResponse().getContentAsString();
36 | Assert.assertEquals(body, "hello, " + name + "!");
37 | });
38 | }
39 |
40 | private String basicAuthorizationHeader(String u, String p) {
41 | String auth = u + ':' + p;
42 | byte[] encoded = Base64.getEncoder()
43 | .encode(auth.getBytes(StandardCharsets.ISO_8859_1));
44 | return "Basic " + new String(encoded);
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/login/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | login
7 | jar
8 |
9 | livelessons
10 | authentication
11 | 0.0.1-SNAPSHOT
12 | ..
13 |
14 |
15 |
16 | com.h2database
17 | h2
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter
22 |
23 |
24 | org.projectlombok
25 | lombok
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-security
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-thymeleaf
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-actuator
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-starter-web
42 |
43 |
44 | nz.net.ultraq.thymeleaf
45 | thymeleaf-layout-dialect
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-devtools
50 |
51 |
52 |
53 | org.springframework.boot
54 | spring-boot-starter-test
55 | test
56 |
57 |
58 | org.springframework.security
59 | spring-security-test
60 | test
61 |
62 |
63 | org.seleniumhq.selenium
64 | htmlunit-driver
65 | test
66 |
67 |
68 | org.seleniumhq.selenium
69 | selenium-support
70 | test
71 |
72 |
77 |
78 |
79 |
80 |
81 |
82 | org.springframework.boot
83 | spring-boot-maven-plugin
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/login/src/main/java/livelessons/LoginApplication.java:
--------------------------------------------------------------------------------
1 | package livelessons;
2 |
3 | import org.apache.commons.logging.Log;
4 | import org.apache.commons.logging.LogFactory;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
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.stereotype.Controller;
11 | import org.springframework.web.bind.annotation.ControllerAdvice;
12 | import org.springframework.web.bind.annotation.GetMapping;
13 | import org.springframework.web.bind.annotation.ModelAttribute;
14 |
15 | import java.security.Principal;
16 |
17 | @SpringBootApplication
18 | public class LoginApplication {
19 |
20 | public static void main(String[] args) {
21 | SpringApplication.run(LoginApplication.class, args);
22 | }
23 |
24 | }
25 |
26 | @ControllerAdvice
27 | class SecurityControllerAdvice {
28 |
29 | @ModelAttribute("currentUser")
30 | Principal currentUser(Principal principal) {
31 | return principal;
32 | }
33 |
34 | }
35 |
36 | @Controller
37 | class LoginController {
38 |
39 | @GetMapping("/")
40 | String index() {
41 | return "hidden";
42 | }
43 |
44 | @GetMapping("/logout-success")
45 | String logout() {
46 | return "logout";
47 | }
48 |
49 | @GetMapping("/login")
50 | String login() {
51 | return "login";
52 | }
53 |
54 | }
55 |
56 | @EnableWebSecurity
57 | class SecurityConfig extends WebSecurityConfigurerAdapter {
58 |
59 | @Override
60 | protected void configure(HttpSecurity http) throws Exception {
61 | http.authorizeRequests().anyRequest().authenticated();
62 | http.logout().logoutUrl("/logout").logoutSuccessUrl("/logout-success")
63 | .permitAll();
64 | http.formLogin().loginPage("/login").permitAll();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/login/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | # expose the Actuator endpoints
2 | management.endpoints.web.exposure.include=*
3 | management.endpoint.health.show-details=always
4 |
5 | # for Spring Security
6 | spring.security.user.name=user
7 | spring.security.user.password=password
--------------------------------------------------------------------------------
/login/src/main/resources/templates/hidden.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Yahaha! You Found Me!
4 |
5 |
6 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/login/src/main/resources/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | Spring Security Livelessons
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/login/src/main/resources/templates/login.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | Please Log In
7 |
8 |
9 |
10 |
11 |
Please Log In
12 |
13 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/login/src/main/resources/templates/logout.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | Goodbye!
7 |
8 |
9 |
10 |
..Don't Forget to Write
11 |
12 |
13 |
--------------------------------------------------------------------------------
/login/src/test/java/livelessons/LoginApplicationTests.java:
--------------------------------------------------------------------------------
1 | package livelessons;
2 |
3 | import livelessons.webdriver.HiddenPage;
4 | import livelessons.webdriver.LoginPage;
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 | import org.openqa.selenium.WebDriver;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.boot.autoconfigure.security.SecurityProperties;
10 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
11 | import org.springframework.boot.test.context.SpringBootTest;
12 | import org.springframework.test.context.junit4.SpringRunner;
13 |
14 | @SpringBootTest
15 | @AutoConfigureMockMvc
16 | @RunWith(SpringRunner.class)
17 | public class LoginApplicationTests {
18 |
19 | @Autowired
20 | private WebDriver driver;
21 |
22 | @Autowired
23 | private SecurityProperties securityProperties;
24 |
25 | @Test
26 | public void requiresLogin() {
27 | HiddenPage.to(this.driver, LoginPage.class).assertAt();
28 | }
29 |
30 | @Test
31 | public void loginFailure() {
32 | HiddenPage.to(this.driver, LoginPage.class).form().username("user")
33 | .password("invalid").login(LoginPage.class).assertAt();
34 | }
35 |
36 | @Test
37 | public void loginSuccess() {
38 | HiddenPage.to(this.driver, LoginPage.class).form()
39 | .username(this.securityProperties.getUser().getName())
40 | .password(this.securityProperties.getUser().getPassword())
41 | .login(HiddenPage.class).assertAt();
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/login/src/test/java/livelessons/webdriver/HiddenPage.java:
--------------------------------------------------------------------------------
1 | package livelessons.webdriver;
2 |
3 | import org.openqa.selenium.WebDriver;
4 | import org.openqa.selenium.support.PageFactory;
5 |
6 | import static org.assertj.core.api.Assertions.assertThat;
7 |
8 | public class HiddenPage {
9 |
10 | private WebDriver driver;
11 |
12 | public HiddenPage(WebDriver driver) {
13 | this.driver = driver;
14 | }
15 |
16 | public static T to(WebDriver driver, Class page) {
17 | driver.get("http://localhost:8080/");
18 | return (T) PageFactory.initElements(driver, page);
19 | }
20 |
21 | public void assertAt() {
22 | assertThat(this.driver.getTitle()).endsWith("Yahaha! You Found Me!");
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/login/src/test/java/livelessons/webdriver/LoginPage.java:
--------------------------------------------------------------------------------
1 | package livelessons.webdriver;
2 |
3 | import org.openqa.selenium.SearchContext;
4 | import org.openqa.selenium.WebDriver;
5 | import org.openqa.selenium.WebElement;
6 | import org.openqa.selenium.support.FindBy;
7 | import org.openqa.selenium.support.PageFactory;
8 | import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
9 |
10 | import static org.assertj.core.api.Assertions.assertThat;
11 |
12 | public class LoginPage {
13 |
14 | private WebDriver driver;
15 |
16 | public LoginPage(WebDriver driver) {
17 | this.driver = driver;
18 | }
19 |
20 | public void assertAt() {
21 | assertThat(this.driver.getTitle()).endsWith("Please Log In");
22 | }
23 |
24 | public Form form() {
25 | return new Form(this.driver);
26 | }
27 |
28 | public class Form {
29 |
30 | @FindBy(name = "username")
31 | private WebElement username;
32 |
33 | @FindBy(name = "password")
34 | private WebElement password;
35 |
36 | @FindBy(name = "submit")
37 | private WebElement button;
38 |
39 | public Form(SearchContext context) {
40 | PageFactory.initElements(new DefaultElementLocatorFactory(context), this);
41 | }
42 |
43 | public Form username(String username) {
44 | this.username.sendKeys(username);
45 | return this;
46 | }
47 |
48 | public Form password(String password) {
49 | this.password.sendKeys(password);
50 | return this;
51 | }
52 |
53 | public T login(Class page) {
54 | this.button.click();
55 | return PageFactory.initElements(LoginPage.this.driver, page);
56 | }
57 |
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/login/src/test/resources/logback-test.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/password-migration/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/password-migration/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/password-migration/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/password-migration/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/password-migration/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/password-migration/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | password-migration
7 | jar
8 |
9 |
10 | livelessons
11 | authentication
12 | 0.0.1-SNAPSHOT
13 | ..
14 |
15 |
16 |
17 |
18 | org.springframework.boot
19 | spring-boot-starter-security
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-web
24 |
25 |
26 |
27 | org.projectlombok
28 | lombok
29 | true
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-test
34 | test
35 |
36 |
37 | org.springframework.security
38 | spring-security-test
39 | test
40 |
41 |
42 |
43 |
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-maven-plugin
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/password-migration/src/main/java/com/example/passwordmigration/CustomAuthenticationApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.passwordmigration;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.security.core.userdetails.UserDetails;
7 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
8 | import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
9 | import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
10 | import org.springframework.security.crypto.password.PasswordEncoder;
11 |
12 | import java.util.Arrays;
13 | import java.util.Collection;
14 | import java.util.Collections;
15 |
16 | @SpringBootApplication
17 | public class CustomAuthenticationApplication {
18 |
19 | // @Bean
20 | PasswordEncoder oldPasswordEncoder() {
21 | String md5 = "MD5";
22 | return new DelegatingPasswordEncoder(md5,
23 | Collections.singletonMap(md5, new MessageDigestPasswordEncoder(md5)));
24 | }
25 |
26 | @Bean
27 | PasswordEncoder passwordEncoder() {
28 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
29 | }
30 |
31 | @Bean
32 | CustomUserDetailsService customUserDetailsService() {
33 | Collection users = Arrays.asList(
34 | new CustomUserDetails("jlong", oldPasswordEncoder().encode("password"),
35 | true, "USER"),
36 | new CustomUserDetails("rwinch", oldPasswordEncoder().encode("password"),
37 | true, "USER", "ADMIN"));
38 | return new CustomUserDetailsService(users);
39 | }
40 |
41 | public static void main(String[] args) {
42 | SpringApplication.run(CustomAuthenticationApplication.class, args);
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/password-migration/src/main/java/com/example/passwordmigration/CustomSecurityConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.example.passwordmigration;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
5 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
6 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
7 |
8 | @Configuration
9 | @EnableWebSecurity
10 | class CustomSecurityConfiguration extends WebSecurityConfigurerAdapter {
11 |
12 | @Override
13 | protected void configure(HttpSecurity http) throws Exception {
14 | http.httpBasic();
15 | http.authorizeRequests().anyRequest().authenticated();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/password-migration/src/main/java/com/example/passwordmigration/CustomUserDetails.java:
--------------------------------------------------------------------------------
1 | package com.example.passwordmigration;
2 |
3 | import org.springframework.security.core.GrantedAuthority;
4 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
5 | import org.springframework.security.core.userdetails.UserDetails;
6 |
7 | import java.util.Collection;
8 | import java.util.Set;
9 | import java.util.stream.Collectors;
10 | import java.util.stream.Stream;
11 |
12 | class CustomUserDetails implements UserDetails {
13 |
14 | private final Set authorities;
15 |
16 | private final String username, password;
17 |
18 | private final boolean active;
19 |
20 | CustomUserDetails(String username, String password, boolean active,
21 | String... authorities) {
22 | this.username = username;
23 | this.password = password;
24 | this.active = active;
25 | this.authorities = Stream.of(authorities).map(SimpleGrantedAuthority::new)
26 | .collect(Collectors.toSet());
27 | }
28 |
29 | @Override
30 | public Collection extends GrantedAuthority> getAuthorities() {
31 | return this.authorities;
32 | }
33 |
34 | @Override
35 | public String getPassword() {
36 | return this.password;
37 | }
38 |
39 | @Override
40 | public String getUsername() {
41 | return this.username;
42 | }
43 |
44 | @Override
45 | public boolean isAccountNonExpired() {
46 | return this.active;
47 | }
48 |
49 | @Override
50 | public boolean isAccountNonLocked() {
51 | return this.active;
52 | }
53 |
54 | @Override
55 | public boolean isCredentialsNonExpired() {
56 | return this.active;
57 | }
58 |
59 | @Override
60 | public boolean isEnabled() {
61 | return this.active;
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/password-migration/src/main/java/com/example/passwordmigration/CustomUserDetailsService.java:
--------------------------------------------------------------------------------
1 | package com.example.passwordmigration;
2 |
3 | import lombok.extern.log4j.Log4j2;
4 | import org.springframework.security.core.GrantedAuthority;
5 | import org.springframework.security.core.userdetails.UserDetails;
6 | import org.springframework.security.core.userdetails.UserDetailsPasswordService;
7 | import org.springframework.security.core.userdetails.UserDetailsService;
8 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
9 |
10 | import java.util.Collection;
11 | import java.util.Map;
12 | import java.util.concurrent.ConcurrentHashMap;
13 |
14 | @Log4j2
15 | class CustomUserDetailsService implements UserDetailsService, UserDetailsPasswordService {
16 |
17 | private final Map users = new ConcurrentHashMap<>();
18 |
19 | public CustomUserDetailsService(Collection seedUsers) {
20 | seedUsers.forEach(user -> this.users.put(user.getUsername(), user));
21 | this.users.forEach((k, v) -> log.info(k + "=" + v.getPassword()));
22 | }
23 |
24 | @Override
25 | public UserDetails loadUserByUsername(String username)
26 | throws UsernameNotFoundException {
27 | if (this.users.containsKey(username)) {
28 | return this.users.get(username);
29 | }
30 | throw new UsernameNotFoundException(String.format("couldn't find %s!", username));
31 | }
32 |
33 | @Override
34 | public UserDetails updatePassword(UserDetails user, String newPassword) {
35 | log.info("prompted to updated password for user " + user.getUsername() + " to "
36 | + newPassword);
37 |
38 | this.users.put(user.getUsername(),
39 | new CustomUserDetails(user.getUsername(), newPassword, user.isEnabled(),
40 | user.getAuthorities().stream().map(GrantedAuthority::getAuthority)
41 | .toArray(String[]::new)));
42 |
43 | return this.loadUserByUsername(user.getUsername());
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/password-migration/src/main/java/com/example/passwordmigration/GreetingRestController.java:
--------------------------------------------------------------------------------
1 | package com.example.passwordmigration;
2 |
3 | import org.springframework.web.bind.annotation.GetMapping;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | import java.security.Principal;
7 |
8 | @RestController
9 | class GreetingRestController {
10 |
11 | @GetMapping("/greeting")
12 | String greet(Principal p) {
13 | return "greetings, " + p.getName() + "!";
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/password-migration/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/password-migration/src/main/resources/application.properties
--------------------------------------------------------------------------------
/password-migration/src/test/java/com/example/passwordmigration/PasswordMigrationApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.passwordmigration;
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 PasswordMigrationApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | livelessons
7 | authentication
8 | 0.0.1-SNAPSHOT
9 | pom
10 |
11 | org.springframework.boot
12 | spring-boot-starter-parent
13 | 2.1.0.RC1
14 |
15 |
16 |
17 | 0.0.6
18 |
19 |
20 |
21 | login
22 | user-details
23 | password-migration
24 | xauth
25 | xauth-app
26 | authentication-provider
27 |
28 |
29 |
30 |
31 | org.webjars
32 | bootstrap
33 | 4.0.0-alpha.6-1
34 |
35 |
36 | org.webjars
37 | tether
38 | 1.4.0
39 |
40 |
41 | org.webjars
42 | jquery
43 | 3.1.1
44 |
45 |
46 | org.seleniumhq.selenium
47 | htmlunit-driver
48 | ${selenium-htmlunit.version}
49 | test
50 |
51 |
52 | org.seleniumhq.selenium
53 | selenium-support
54 | ${selenium.version}
55 | test
56 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | spring-snapshots
70 | Spring Snapshots
71 | https://repo.spring.io/snapshot
72 |
73 | true
74 |
75 |
76 |
77 | spring-milestones
78 | Spring Milestones
79 | https://repo.spring.io/milestone
80 |
81 | false
82 |
83 |
84 |
85 |
86 |
87 |
88 | spring-snapshots
89 | Spring Snapshots
90 | https://repo.spring.io/snapshot
91 |
92 | true
93 |
94 |
95 |
96 | spring-milestones
97 | Spring Milestones
98 | https://repo.spring.io/milestone
99 |
100 | false
101 |
102 |
103 |
104 |
105 |
106 |
107 | io.spring.javaformat
108 | spring-javaformat-maven-plugin
109 | ${spring-javaformat-maven-plugin.version}
110 |
111 |
112 | validate
113 | true
114 |
115 | validate
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/studio/auditing/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/studio/auditing/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/auditing/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/studio/auditing/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/studio/auditing/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/studio/auditing/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | custom-authentication
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | custom-authentication
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.1.0.BUILD-SNAPSHOT
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-actuator
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-security
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-web
39 |
40 |
41 |
42 | org.projectlombok
43 | lombok
44 | true
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-test
49 | test
50 |
51 |
52 | org.springframework.security
53 | spring-security-test
54 | test
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-maven-plugin
63 |
64 |
65 |
66 |
67 |
68 |
69 | spring-snapshots
70 | Spring Snapshots
71 | https://repo.spring.io/snapshot
72 |
73 | true
74 |
75 |
76 |
77 | spring-milestones
78 | Spring Milestones
79 | https://repo.spring.io/milestone
80 |
81 | false
82 |
83 |
84 |
85 |
86 |
87 |
88 | spring-snapshots
89 | Spring Snapshots
90 | https://repo.spring.io/snapshot
91 |
92 | true
93 |
94 |
95 |
96 | spring-milestones
97 | Spring Milestones
98 | https://repo.spring.io/milestone
99 |
100 | false
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/studio/auditing/src/main/java/com/example/customauthentication/CustomAuthenticationApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.customauthentication;
2 |
3 | import lombok.extern.log4j.Log4j2;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
12 | import org.springframework.security.core.GrantedAuthority;
13 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
14 | import org.springframework.security.core.userdetails.UserDetails;
15 | import org.springframework.security.core.userdetails.UserDetailsPasswordService;
16 | import org.springframework.security.core.userdetails.UserDetailsService;
17 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
18 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
19 | import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
20 | import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
21 | import org.springframework.security.crypto.password.PasswordEncoder;
22 | import org.springframework.web.bind.annotation.GetMapping;
23 | import org.springframework.web.bind.annotation.RestController;
24 |
25 | import java.security.Principal;
26 | import java.util.*;
27 | import java.util.concurrent.ConcurrentHashMap;
28 | import java.util.stream.Collectors;
29 | import java.util.stream.Stream;
30 |
31 | @SpringBootApplication
32 | public class CustomAuthenticationApplication {
33 |
34 | // @Bean
35 | PasswordEncoder oldPasswordEncoder() {
36 | String md5 = "MD5";
37 | return new DelegatingPasswordEncoder(md5,
38 | Collections.singletonMap(md5, new MessageDigestPasswordEncoder(md5)));
39 | }
40 |
41 | @Bean
42 | PasswordEncoder passwordEncoder() {
43 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
44 | }
45 |
46 | @Bean
47 | CustomUserDetailsService customUserDetailsService() {
48 | Collection users = Arrays.asList(
49 | new CustomUserDetails("jlong", oldPasswordEncoder().encode("password"), true, "USER"),
50 | new CustomUserDetails("rwinch", oldPasswordEncoder().encode("password"), true, "USER", "ADMIN")
51 | );
52 | return new CustomUserDetailsService(users);
53 | }
54 |
55 | public static void main(String[] args) {
56 | SpringApplication.run(CustomAuthenticationApplication.class, args);
57 | }
58 | }
59 |
60 | @RestController
61 | class GreetingRestController {
62 |
63 | @GetMapping("/greeting")
64 | String greet(Principal p) {
65 | return "greetings, " + p.getName() + "!";
66 | }
67 | }
68 |
69 | @Configuration
70 | @EnableWebSecurity
71 | class CustomSecurityConfiguration extends WebSecurityConfigurerAdapter {
72 |
73 | @Override
74 | protected void configure(HttpSecurity http) throws Exception {
75 | http.httpBasic();
76 | http.authorizeRequests().anyRequest().authenticated();
77 | }
78 | }
79 |
80 | @Log4j2
81 | class CustomUserDetailsService implements UserDetailsService,
82 | UserDetailsPasswordService {
83 |
84 | private final Map users = new ConcurrentHashMap<>();
85 |
86 | public CustomUserDetailsService(Collection seedUsers) {
87 | seedUsers.forEach(user -> this.users.put(user.getUsername(), user));
88 | this.users.forEach((k, v) -> log.info(k + "=" + v.getPassword()));
89 | }
90 |
91 | @Override
92 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
93 | if (this.users.containsKey(username)) {
94 | return this.users.get(username);
95 | }
96 | throw new UsernameNotFoundException(String.format("couldn't find %s!", username));
97 | }
98 |
99 | @Override
100 | public UserDetails updatePassword(UserDetails user, String newPassword) {
101 | log.info("prompted to updated password for user " + user.getUsername() + " to " + newPassword);
102 |
103 | this.users.put(user.getUsername(), new CustomUserDetails(
104 | user.getUsername(),
105 | newPassword,
106 | user.isEnabled(),
107 | user.getAuthorities().stream().map(GrantedAuthority::getAuthority).toArray(String[]::new)
108 | ));
109 |
110 | return this.loadUserByUsername(user.getUsername());
111 | }
112 | }
113 |
114 |
115 | class CustomUserDetails implements UserDetails {
116 |
117 | private final Set authorities;
118 | private final String username, password;
119 | private final boolean active;
120 |
121 | public CustomUserDetails(String username, String password, boolean active, String... authorities) {
122 | this.username = username;
123 | this.password = password;
124 | this.active = active;
125 | this.authorities = Stream
126 | .of(authorities)
127 | .map(SimpleGrantedAuthority::new)
128 | .collect(Collectors.toSet());
129 | }
130 |
131 | @Override
132 | public Collection extends GrantedAuthority> getAuthorities() {
133 | return this.authorities;
134 | }
135 |
136 | @Override
137 | public String getPassword() {
138 | return this.password;
139 | }
140 |
141 | @Override
142 | public String getUsername() {
143 | return this.username;
144 | }
145 |
146 | @Override
147 | public boolean isAccountNonExpired() {
148 | return this.active;
149 | }
150 |
151 | @Override
152 | public boolean isAccountNonLocked() {
153 | return this.active;
154 | }
155 |
156 | @Override
157 | public boolean isCredentialsNonExpired() {
158 | return this.active;
159 | }
160 |
161 | @Override
162 | public boolean isEnabled() {
163 | return this.active;
164 | }
165 | }
--------------------------------------------------------------------------------
/studio/auditing/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | management.endpoints.web.exposure.include=*
2 |
--------------------------------------------------------------------------------
/studio/auditing/src/test/java/com/example/customauthentication/CustomAuthenticationApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.customauthentication;
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 CustomAuthenticationApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/studio/custom-authentication/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/studio/custom-authentication/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/custom-authentication/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/studio/custom-authentication/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/studio/custom-authentication/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/studio/custom-authentication/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | custom-authentication
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | custom-authentication
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.1.0.BUILD-SNAPSHOT
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-actuator
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-security
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-web
39 |
40 |
41 |
42 | org.projectlombok
43 | lombok
44 | true
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-test
49 | test
50 |
51 |
52 | org.springframework.security
53 | spring-security-test
54 | test
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-maven-plugin
63 |
64 |
65 |
66 |
67 |
68 |
69 | spring-snapshots
70 | Spring Snapshots
71 | https://repo.spring.io/snapshot
72 |
73 | true
74 |
75 |
76 |
77 | spring-milestones
78 | Spring Milestones
79 | https://repo.spring.io/milestone
80 |
81 | false
82 |
83 |
84 |
85 |
86 |
87 |
88 | spring-snapshots
89 | Spring Snapshots
90 | https://repo.spring.io/snapshot
91 |
92 | true
93 |
94 |
95 |
96 | spring-milestones
97 | Spring Milestones
98 | https://repo.spring.io/milestone
99 |
100 | false
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/studio/custom-authentication/src/main/java/com/example/customauthentication/CustomAuthenticationApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.customauthentication;
2 |
3 | import lombok.extern.log4j.Log4j2;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
12 | import org.springframework.security.core.GrantedAuthority;
13 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
14 | import org.springframework.security.core.userdetails.UserDetails;
15 | import org.springframework.security.core.userdetails.UserDetailsPasswordService;
16 | import org.springframework.security.core.userdetails.UserDetailsService;
17 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
18 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
19 | import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
20 | import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
21 | import org.springframework.security.crypto.password.PasswordEncoder;
22 | import org.springframework.web.bind.annotation.GetMapping;
23 | import org.springframework.web.bind.annotation.RestController;
24 |
25 | import java.security.Principal;
26 | import java.util.*;
27 | import java.util.concurrent.ConcurrentHashMap;
28 | import java.util.stream.Collectors;
29 | import java.util.stream.Stream;
30 |
31 | @SpringBootApplication
32 | public class CustomAuthenticationApplication {
33 |
34 | // @Bean
35 | PasswordEncoder oldPasswordEncoder() {
36 | String md5 = "MD5";
37 | return new DelegatingPasswordEncoder(md5,
38 | Collections.singletonMap(md5, new MessageDigestPasswordEncoder(md5)));
39 | }
40 |
41 | @Bean
42 | PasswordEncoder passwordEncoder() {
43 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
44 | }
45 |
46 | @Bean
47 | CustomUserDetailsService customUserDetailsService() {
48 | Collection users = Arrays.asList(
49 | new CustomUserDetails("jlong", oldPasswordEncoder().encode("password"), true, "USER"),
50 | new CustomUserDetails("rwinch", oldPasswordEncoder().encode("password"), true, "USER", "ADMIN")
51 | );
52 | return new CustomUserDetailsService(users);
53 | }
54 |
55 | public static void main(String[] args) {
56 | SpringApplication.run(CustomAuthenticationApplication.class, args);
57 | }
58 | }
59 |
60 | @RestController
61 | class GreetingRestController {
62 |
63 | @GetMapping("/greeting")
64 | String greet(Principal p) {
65 | return "greetings, " + p.getName() + "!";
66 | }
67 | }
68 |
69 | @Configuration
70 | @EnableWebSecurity
71 | class CustomSecurityConfiguration extends WebSecurityConfigurerAdapter {
72 |
73 | @Override
74 | protected void configure(HttpSecurity http) throws Exception {
75 | http.httpBasic();
76 | http.authorizeRequests().anyRequest().authenticated();
77 | }
78 | }
79 |
80 | @Log4j2
81 | class CustomUserDetailsService implements UserDetailsService,
82 | UserDetailsPasswordService {
83 |
84 | private final Map users = new ConcurrentHashMap<>();
85 |
86 | public CustomUserDetailsService(Collection seedUsers) {
87 | seedUsers.forEach(user -> this.users.put(user.getUsername(), user));
88 | this.users.forEach((k, v) -> log.info(k + "=" + v.getPassword()));
89 | }
90 |
91 | @Override
92 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
93 | if (this.users.containsKey(username)) {
94 | return this.users.get(username);
95 | }
96 | throw new UsernameNotFoundException(String.format("couldn't find %s!", username));
97 | }
98 |
99 | @Override
100 | public UserDetails updatePassword(UserDetails user, String newPassword) {
101 | log.info("prompted to updated password for user " + user.getUsername() + " to " + newPassword);
102 |
103 | this.users.put(user.getUsername(), new CustomUserDetails(
104 | user.getUsername(),
105 | newPassword,
106 | user.isEnabled(),
107 | user.getAuthorities().stream().map(GrantedAuthority::getAuthority).toArray(String[]::new)
108 | ));
109 |
110 | return this.loadUserByUsername(user.getUsername());
111 | }
112 | }
113 |
114 |
115 | class CustomUserDetails implements UserDetails {
116 |
117 | private final Set authorities;
118 | private final String username, password;
119 | private final boolean active;
120 |
121 | public CustomUserDetails(String username, String password, boolean active, String... authorities) {
122 | this.username = username;
123 | this.password = password;
124 | this.active = active;
125 | this.authorities = Stream
126 | .of(authorities)
127 | .map(SimpleGrantedAuthority::new)
128 | .collect(Collectors.toSet());
129 | }
130 |
131 | @Override
132 | public Collection extends GrantedAuthority> getAuthorities() {
133 | return this.authorities;
134 | }
135 |
136 | @Override
137 | public String getPassword() {
138 | return this.password;
139 | }
140 |
141 | @Override
142 | public String getUsername() {
143 | return this.username;
144 | }
145 |
146 | @Override
147 | public boolean isAccountNonExpired() {
148 | return this.active;
149 | }
150 |
151 | @Override
152 | public boolean isAccountNonLocked() {
153 | return this.active;
154 | }
155 |
156 | @Override
157 | public boolean isCredentialsNonExpired() {
158 | return this.active;
159 | }
160 |
161 | @Override
162 | public boolean isEnabled() {
163 | return this.active;
164 | }
165 | }
--------------------------------------------------------------------------------
/studio/custom-authentication/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | management.endpoints.web.exposure.include=*
2 |
--------------------------------------------------------------------------------
/studio/custom-authentication/src/test/java/com/example/customauthentication/CustomAuthenticationApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.customauthentication;
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 CustomAuthenticationApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/studio/inmemory/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/studio/inmemory/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/inmemory/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/studio/inmemory/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/studio/inmemory/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/studio/inmemory/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | inmemory
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | inmemory
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.3.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-security
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-web
35 |
36 |
37 |
38 | org.projectlombok
39 | lombok
40 | true
41 |
42 |
43 | org.springframework.boot
44 | spring-boot-starter-test
45 | test
46 |
47 |
48 | org.springframework.security
49 | spring-security-test
50 | test
51 |
52 |
53 |
54 |
55 |
56 |
57 | org.springframework.boot
58 | spring-boot-maven-plugin
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/studio/inmemory/src/main/java/com/example/inmemory/InmemoryApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.inmemory;
2 |
3 | import org.springframework.beans.factory.InitializingBean;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
11 | import org.springframework.security.core.userdetails.User;
12 | import org.springframework.security.core.userdetails.UserDetails;
13 | import org.springframework.security.provisioning.InMemoryUserDetailsManager;
14 | import org.springframework.security.provisioning.UserDetailsManager;
15 | import org.springframework.web.bind.annotation.GetMapping;
16 | import org.springframework.web.bind.annotation.RestController;
17 |
18 | import java.security.Principal;
19 |
20 | @SpringBootApplication
21 | public class InmemoryApplication {
22 |
23 | @Bean
24 | UserDetailsManager memory() {
25 | return new InMemoryUserDetailsManager();
26 | }
27 |
28 | @Bean
29 | InitializingBean initializer(UserDetailsManager manager) {
30 | return () -> {
31 |
32 | UserDetails josh = User.withDefaultPasswordEncoder().username("jlong").password("password").roles("USER").build();
33 | manager.createUser(josh);
34 |
35 | UserDetails rob = User.withUserDetails(josh).username("rwinch").build();
36 | manager.createUser(rob);
37 | };
38 | }
39 |
40 |
41 | public static void main(String[] args) {
42 | SpringApplication.run(InmemoryApplication.class, args);
43 | }
44 | }
45 |
46 |
47 | @RestController
48 | class GreetingsRestController {
49 |
50 | @GetMapping("/greeting")
51 | String greeting(Principal principal) {
52 | return "hello, " + principal.getName() + "!";
53 | }
54 | }
55 |
56 | @Configuration
57 | @EnableWebSecurity
58 | class SecurityConfiguration extends WebSecurityConfigurerAdapter {
59 |
60 | @Override
61 | protected void configure(HttpSecurity http) throws Exception {
62 |
63 | http
64 | .httpBasic();
65 |
66 | http
67 | .authorizeRequests().anyRequest().authenticated();
68 | }
69 | }
--------------------------------------------------------------------------------
/studio/inmemory/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/inmemory/src/main/resources/application.properties
--------------------------------------------------------------------------------
/studio/inmemory/src/test/java/com/example/inmemory/InmemoryApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.inmemory;
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 InmemoryApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/studio/jdbc/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/studio/jdbc/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/jdbc/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/studio/jdbc/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/studio/jdbc/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/studio/jdbc/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/studio/jdbc/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | jdbc
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | jdbc
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.3.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-security
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-web
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-jdbc
39 |
40 |
41 |
42 | com.h2database
43 | h2
44 | runtime
45 |
46 |
47 | org.projectlombok
48 | lombok
49 | true
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-test
54 | test
55 |
56 |
57 | org.springframework.security
58 | spring-security-test
59 | test
60 |
61 |
62 |
63 |
64 |
65 |
66 | org.springframework.boot
67 | spring-boot-maven-plugin
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/studio/jdbc/src/main/java/com/example/jdbc/JdbcApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.jdbc;
2 |
3 | import org.springframework.beans.factory.InitializingBean;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
11 | import org.springframework.security.core.userdetails.User;
12 | import org.springframework.security.core.userdetails.UserDetails;
13 | import org.springframework.security.provisioning.JdbcUserDetailsManager;
14 | import org.springframework.security.provisioning.UserDetailsManager;
15 | import org.springframework.web.bind.annotation.GetMapping;
16 | import org.springframework.web.bind.annotation.RestController;
17 |
18 | import javax.sql.DataSource;
19 | import java.security.Principal;
20 |
21 | @SpringBootApplication
22 | public class JdbcApplication {
23 |
24 | @Bean
25 | UserDetailsManager memory(DataSource ds) {
26 | JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager();
27 | jdbcUserDetailsManager.setDataSource(ds);
28 | return jdbcUserDetailsManager;
29 | }
30 |
31 | @Bean
32 | InitializingBean initializer(UserDetailsManager manager) {
33 | return () -> {
34 |
35 | UserDetails josh = User.withDefaultPasswordEncoder().username("jlong").password("password").roles("USER").build();
36 | manager.createUser(josh);
37 |
38 | UserDetails rob = User.withUserDetails(josh).username("rwinch").build();
39 | manager.createUser(rob);
40 | };
41 | }
42 |
43 |
44 | public static void main(String[] args) {
45 | SpringApplication.run(JdbcApplication.class, args);
46 | }
47 | }
48 |
49 |
50 | @RestController
51 | class GreetingsRestController {
52 |
53 | @GetMapping("/greeting")
54 | String greeting(Principal principal) {
55 | return "hello, " + principal.getName() + "!";
56 | }
57 | }
58 |
59 | @Configuration
60 | @EnableWebSecurity
61 | class SecurityConfiguration extends WebSecurityConfigurerAdapter {
62 |
63 | @Override
64 | protected void configure(HttpSecurity http) throws Exception {
65 |
66 | http
67 | .httpBasic();
68 |
69 | http
70 | .authorizeRequests().anyRequest().authenticated();
71 | }
72 | }
--------------------------------------------------------------------------------
/studio/jdbc/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/jdbc/src/main/resources/application.properties
--------------------------------------------------------------------------------
/studio/jdbc/src/main/resources/schema.sql:
--------------------------------------------------------------------------------
1 | drop table if exists users;
2 |
3 | create table users (
4 | username varchar(50) not null primary key,
5 | password varchar(500) not null,
6 | enabled boolean not null
7 | );
8 |
9 | drop table if exists authorities;
10 | create table authorities (
11 | username varchar(255) not null,
12 | authority varchar(50) not null,
13 | constraint fk_authorities_users foreign key (username) references users (username)
14 | );
15 |
16 | create unique index ix_auth_username
17 | on authorities (username, authority);
--------------------------------------------------------------------------------
/studio/jdbc/src/test/java/com/example/jdbc/JdbcApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.jdbc;
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 JdbcApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/studio/ldap/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/studio/ldap/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/ldap/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/studio/ldap/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/studio/ldap/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/studio/ldap/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/studio/ldap/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | ldap
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | ldap
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.3.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-security
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-web
39 |
40 |
41 | org.springframework.security
42 | spring-security-ldap
43 |
44 |
45 | org.springframework.ldap
46 | spring-ldap-core
47 |
48 |
49 | com.unboundid
50 | unboundid-ldapsdk
51 |
52 |
53 | org.projectlombok
54 | lombok
55 | true
56 |
57 |
58 | org.springframework.boot
59 | spring-boot-starter-test
60 | test
61 |
62 |
63 | org.springframework.security
64 | spring-security-test
65 | test
66 |
67 |
68 |
69 |
70 |
71 |
72 | org.springframework.boot
73 | spring-boot-maven-plugin
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/studio/ldap/src/main/java/com/example/ldap/LdapApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.ldap;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.password.LdapShaPasswordEncoder;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 | import org.springframework.web.bind.annotation.RestController;
13 |
14 | import java.security.Principal;
15 |
16 | @SpringBootApplication
17 | public class LdapApplication {
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(LdapApplication.class, args);
21 | }
22 | }
23 |
24 | @RestController
25 | class GreetingsRestController {
26 |
27 | @GetMapping("/greeting")
28 | String greet(Principal p) {
29 | return "hello " + p.getName() + "!";
30 | }
31 | }
32 |
33 | @Configuration
34 | @EnableWebSecurity
35 | class LdapSecurityConfiguration extends WebSecurityConfigurerAdapter {
36 |
37 | @Override
38 | protected void configure(AuthenticationManagerBuilder auth) throws Exception {
39 | //@formatter:off
40 | auth
41 | .ldapAuthentication()
42 | .userDnPatterns("uid={0},ou=people")
43 | .groupSearchBase("ou=groups")
44 | .contextSource()
45 | .url("ldap://127.0.0.1:8389/dc=springframework,dc=org")
46 | .and()
47 | .passwordCompare()
48 | .passwordAttribute("userPassword")
49 | .passwordEncoder(new LdapShaPasswordEncoder());
50 | //@formatter:on
51 | }
52 |
53 | @Override
54 | protected void configure(HttpSecurity http) throws Exception {
55 |
56 | http.httpBasic();
57 |
58 | http.authorizeRequests().anyRequest().authenticated();
59 | }
60 | }
--------------------------------------------------------------------------------
/studio/ldap/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.ldap.embedded.port=8389
2 | spring.ldap.embedded.ldif=classpath:test-server.ldif
3 | spring.ldap.embedded.base-dn=dc=springframework,dc=org
--------------------------------------------------------------------------------
/studio/ldap/src/main/resources/test-server.ldif:
--------------------------------------------------------------------------------
1 | dn: dc=springframework,dc=org
2 | objectclass: top
3 | objectclass: domain
4 | objectclass: extensibleObject
5 | dc: springframework
6 |
7 | dn: ou=groups,dc=springframework,dc=org
8 | objectclass: top
9 | objectclass: organizationalUnit
10 | ou: groups
11 |
12 | dn: ou=subgroups,ou=groups,dc=springframework,dc=org
13 | objectclass: top
14 | objectclass: organizationalUnit
15 | ou: subgroups
16 |
17 | dn: ou=people,dc=springframework,dc=org
18 | objectclass: top
19 | objectclass: organizationalUnit
20 | ou: people
21 |
22 | dn: ou=space cadets,dc=springframework,dc=org
23 | objectclass: top
24 | objectclass: organizationalUnit
25 | ou: space cadets
26 |
27 | dn: ou=\"quoted people\",dc=springframework,dc=org
28 | objectclass: top
29 | objectclass: organizationalUnit
30 | ou: "quoted people"
31 |
32 | dn: ou=otherpeople,dc=springframework,dc=org
33 | objectclass: top
34 | objectclass: organizationalUnit
35 | ou: otherpeople
36 |
37 | dn: uid=ben,ou=people,dc=springframework,dc=org
38 | objectclass: top
39 | objectclass: person
40 | objectclass: organizationalPerson
41 | objectclass: inetOrgPerson
42 | cn: Ben Alex
43 | sn: Alex
44 | uid: ben
45 | userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
46 |
47 | dn: uid=bob,ou=people,dc=springframework,dc=org
48 | objectclass: top
49 | objectclass: person
50 | objectclass: organizationalPerson
51 | objectclass: inetOrgPerson
52 | cn: Bob Hamilton
53 | sn: Hamilton
54 | uid: bob
55 | userPassword: bobspassword
56 |
57 | dn: uid=joe,ou=otherpeople,dc=springframework,dc=org
58 | objectclass: top
59 | objectclass: person
60 | objectclass: organizationalPerson
61 | objectclass: inetOrgPerson
62 | cn: Joe Smeth
63 | sn: Smeth
64 | uid: joe
65 | userPassword: joespassword
66 |
67 | dn: cn=mouse\, jerry,ou=people,dc=springframework,dc=org
68 | objectclass: top
69 | objectclass: person
70 | objectclass: organizationalPerson
71 | objectclass: inetOrgPerson
72 | cn: Mouse, Jerry
73 | sn: Mouse
74 | uid: jerry
75 | userPassword: jerryspassword
76 |
77 | dn: cn=slash/guy,ou=people,dc=springframework,dc=org
78 | objectclass: top
79 | objectclass: person
80 | objectclass: organizationalPerson
81 | objectclass: inetOrgPerson
82 | cn: slash/guy
83 | sn: Slash
84 | uid: slashguy
85 | userPassword: slashguyspassword
86 |
87 | dn: cn=quote\"guy,ou=\"quoted people\",dc=springframework,dc=org
88 | objectclass: top
89 | objectclass: person
90 | objectclass: organizationalPerson
91 | objectclass: inetOrgPerson
92 | cn: quote\"guy
93 | sn: Quote
94 | uid: quoteguy
95 | userPassword: quoteguyspassword
96 |
97 | dn: uid=space cadet,ou=space cadets,dc=springframework,dc=org
98 | objectclass: top
99 | objectclass: person
100 | objectclass: organizationalPerson
101 | objectclass: inetOrgPerson
102 | cn: Space Cadet
103 | sn: Cadet
104 | uid: space cadet
105 | userPassword: spacecadetspassword
106 |
107 |
108 |
109 | dn: cn=developers,ou=groups,dc=springframework,dc=org
110 | objectclass: top
111 | objectclass: groupOfUniqueNames
112 | cn: developers
113 | ou: developer
114 | uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
115 | uniqueMember: uid=bob,ou=people,dc=springframework,dc=org
116 |
117 | dn: cn=managers,ou=groups,dc=springframework,dc=org
118 | objectclass: top
119 | objectclass: groupOfUniqueNames
120 | cn: managers
121 | ou: manager
122 | uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
123 | uniqueMember: cn=mouse\, jerry,ou=people,dc=springframework,dc=org
124 |
125 | dn: cn=submanagers,ou=subgroups,ou=groups,dc=springframework,dc=org
126 | objectclass: top
127 | objectclass: groupOfUniqueNames
128 | cn: submanagers
129 | ou: submanager
130 | uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
--------------------------------------------------------------------------------
/studio/ldap/src/test/java/com/example/ldap/LdapApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.ldap;
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 LdapApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/studio/login/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/studio/login/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/login/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/studio/login/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/studio/login/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/studio/login/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | login
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | login
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.1.0.BUILD-SNAPSHOT
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-actuator
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-security
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-thymeleaf
39 |
40 |
41 | nz.net.ultraq.thymeleaf
42 | thymeleaf-layout-dialect
43 |
44 |
45 | org.springframework.boot
46 | spring-boot-starter-web
47 |
48 |
49 | org.projectlombok
50 | lombok
51 | true
52 |
53 |
54 | org.springframework.boot
55 | spring-boot-starter-test
56 | test
57 |
58 |
59 | org.springframework.security
60 | spring-security-test
61 | test
62 |
63 |
64 |
65 |
66 |
67 |
68 | org.springframework.boot
69 | spring-boot-maven-plugin
70 |
71 |
72 |
73 |
74 |
75 |
76 | spring-snapshots
77 | Spring Snapshots
78 | https://repo.spring.io/snapshot
79 |
80 | true
81 |
82 |
83 |
84 | spring-milestones
85 | Spring Milestones
86 | https://repo.spring.io/milestone
87 |
88 | false
89 |
90 |
91 |
92 |
93 |
94 |
95 | spring-snapshots
96 | Spring Snapshots
97 | https://repo.spring.io/snapshot
98 |
99 | true
100 |
101 |
102 |
103 | spring-milestones
104 | Spring Milestones
105 | https://repo.spring.io/milestone
106 |
107 | false
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/studio/login/src/main/java/com/example/login/LoginApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.login;
2 |
3 | import org.springframework.beans.factory.InitializingBean;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
11 | import org.springframework.security.core.userdetails.User;
12 | import org.springframework.security.core.userdetails.UserDetails;
13 | import org.springframework.security.provisioning.InMemoryUserDetailsManager;
14 | import org.springframework.security.provisioning.UserDetailsManager;
15 | import org.springframework.stereotype.Controller;
16 | import org.springframework.ui.Model;
17 | import org.springframework.web.bind.annotation.ControllerAdvice;
18 | import org.springframework.web.bind.annotation.GetMapping;
19 | import org.springframework.web.bind.annotation.ModelAttribute;
20 |
21 | import java.security.Principal;
22 |
23 | @SpringBootApplication
24 | public class LoginApplication {
25 |
26 | public static void main(String[] args) {
27 | SpringApplication.run(LoginApplication.class, args);
28 | }
29 |
30 | @Bean
31 | UserDetailsManager memory() {
32 | return new InMemoryUserDetailsManager();
33 | }
34 |
35 | @Bean
36 | InitializingBean initializer(UserDetailsManager manager) {
37 | return () -> {
38 |
39 | UserDetails josh = User.withDefaultPasswordEncoder().username("jlong").password("password").roles("USER").build();
40 | manager.createUser(josh);
41 |
42 | UserDetails rob = User.withUserDetails(josh).username("rwinch").build();
43 | manager.createUser(rob);
44 | };
45 | }
46 | }
47 |
48 | @ControllerAdvice
49 | class PrincipalControllerAdvice {
50 |
51 | @ModelAttribute("currentUser")
52 | Principal principal(Principal p) {
53 | return p;
54 | }
55 | }
56 |
57 | @Controller
58 | class LoginController {
59 |
60 | @GetMapping("/")
61 | String index(Model model) {
62 | return "hidden";
63 | }
64 |
65 | @GetMapping("/login")
66 | String login() {
67 | return "login";
68 | }
69 |
70 | @GetMapping("/logout-success")
71 | String logout() {
72 | return "logout";
73 | }
74 |
75 | }
76 |
77 | @Configuration
78 | @EnableWebSecurity
79 | class SecurityConfiguration extends WebSecurityConfigurerAdapter {
80 |
81 | @Override
82 | protected void configure(HttpSecurity http) throws Exception {
83 |
84 | http
85 | .authorizeRequests().anyRequest().authenticated();
86 |
87 | http
88 | .formLogin().loginPage("/login").permitAll();
89 |
90 | http
91 | .logout().logoutUrl("/logout").logoutSuccessUrl("/logout-success").permitAll();
92 | }
93 | }
--------------------------------------------------------------------------------
/studio/login/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/login/src/main/resources/application.properties
--------------------------------------------------------------------------------
/studio/login/src/main/resources/templates/hidden.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Yahaha! You Found Me!
4 |
5 |
6 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/studio/login/src/main/resources/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | Spring Security Livelessons
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/studio/login/src/main/resources/templates/login.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | Please Log In
7 |
8 |
9 |
10 |
11 |
Please Log In
12 |
13 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/studio/login/src/main/resources/templates/logout.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | Goodbye!
7 |
8 |
9 |
10 |
..Don't Forget to Write!
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/studio/login/src/test/java/com/example/login/LoginApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.login;
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 LoginApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/studio/password-encoding-and-migration/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/studio/password-encoding-and-migration/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/studio/password-encoding-and-migration/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/studio/password-encoding-and-migration/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/studio/password-encoding-and-migration/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/studio/password-encoding-and-migration/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.example
7 | custom-authentication
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | custom-authentication
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.1.0.BUILD-SNAPSHOT
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-actuator
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-security
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-web
39 |
40 |
41 |
42 | org.projectlombok
43 | lombok
44 | true
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-test
49 | test
50 |
51 |
52 | org.springframework.security
53 | spring-security-test
54 | test
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-maven-plugin
63 |
64 |
65 |
66 |
67 |
68 |
69 | spring-snapshots
70 | Spring Snapshots
71 | https://repo.spring.io/snapshot
72 |
73 | true
74 |
75 |
76 |
77 | spring-milestones
78 | Spring Milestones
79 | https://repo.spring.io/milestone
80 |
81 | false
82 |
83 |
84 |
85 |
86 |
87 |
88 | spring-snapshots
89 | Spring Snapshots
90 | https://repo.spring.io/snapshot
91 |
92 | true
93 |
94 |
95 |
96 | spring-milestones
97 | Spring Milestones
98 | https://repo.spring.io/milestone
99 |
100 | false
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/studio/password-encoding-and-migration/src/main/java/com/example/customauthentication/CustomAuthenticationApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.customauthentication;
2 |
3 | import lombok.extern.log4j.Log4j2;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
12 | import org.springframework.security.core.GrantedAuthority;
13 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
14 | import org.springframework.security.core.userdetails.UserDetails;
15 | import org.springframework.security.core.userdetails.UserDetailsPasswordService;
16 | import org.springframework.security.core.userdetails.UserDetailsService;
17 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
18 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
19 | import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
20 | import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
21 | import org.springframework.security.crypto.password.PasswordEncoder;
22 | import org.springframework.web.bind.annotation.GetMapping;
23 | import org.springframework.web.bind.annotation.RestController;
24 |
25 | import java.security.Principal;
26 | import java.util.*;
27 | import java.util.concurrent.ConcurrentHashMap;
28 | import java.util.stream.Collectors;
29 | import java.util.stream.Stream;
30 |
31 | @SpringBootApplication
32 | public class CustomAuthenticationApplication {
33 |
34 | // @Bean
35 | PasswordEncoder oldPasswordEncoder() {
36 | String md5 = "MD5";
37 | return new DelegatingPasswordEncoder(md5,
38 | Collections.singletonMap(md5, new MessageDigestPasswordEncoder(md5)));
39 | }
40 |
41 | @Bean
42 | PasswordEncoder passwordEncoder() {
43 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
44 | }
45 |
46 | @Bean
47 | CustomUserDetailsService customUserDetailsService() {
48 | Collection users = Arrays.asList(
49 | new CustomUserDetails("jlong", oldPasswordEncoder().encode("password"), true, "USER"),
50 | new CustomUserDetails("rwinch", oldPasswordEncoder().encode("password"), true, "USER", "ADMIN")
51 | );
52 | return new CustomUserDetailsService(users);
53 | }
54 |
55 | public static void main(String[] args) {
56 | SpringApplication.run(CustomAuthenticationApplication.class, args);
57 | }
58 | }
59 |
60 | @RestController
61 | class GreetingRestController {
62 |
63 | @GetMapping("/greeting")
64 | String greet(Principal p) {
65 | return "greetings, " + p.getName() + "!";
66 | }
67 | }
68 |
69 | @Configuration
70 | @EnableWebSecurity
71 | class CustomSecurityConfiguration extends WebSecurityConfigurerAdapter {
72 |
73 | @Override
74 | protected void configure(HttpSecurity http) throws Exception {
75 | http.httpBasic();
76 | http.authorizeRequests().anyRequest().authenticated();
77 | }
78 | }
79 |
80 | @Log4j2
81 | class CustomUserDetailsService implements UserDetailsService,
82 | UserDetailsPasswordService {
83 |
84 | private final Map users = new ConcurrentHashMap<>();
85 |
86 | public CustomUserDetailsService(Collection seedUsers) {
87 | seedUsers.forEach(user -> this.users.put(user.getUsername(), user));
88 | this.users.forEach((k, v) -> log.info(k + "=" + v.getPassword()));
89 | }
90 |
91 | @Override
92 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
93 | if (this.users.containsKey(username)) {
94 | return this.users.get(username);
95 | }
96 | throw new UsernameNotFoundException(String.format("couldn't find %s!", username));
97 | }
98 |
99 | @Override
100 | public UserDetails updatePassword(UserDetails user, String newPassword) {
101 | log.info("prompted to updated password for user " + user.getUsername() + " to " + newPassword);
102 |
103 | this.users.put(user.getUsername(), new CustomUserDetails(
104 | user.getUsername(),
105 | newPassword,
106 | user.isEnabled(),
107 | user.getAuthorities().stream().map(GrantedAuthority::getAuthority).toArray(String[]::new)
108 | ));
109 |
110 | return this.loadUserByUsername(user.getUsername());
111 | }
112 | }
113 |
114 |
115 | class CustomUserDetails implements UserDetails {
116 |
117 | private final Set authorities;
118 | private final String username, password;
119 | private final boolean active;
120 |
121 | public CustomUserDetails(String username, String password, boolean active, String... authorities) {
122 | this.username = username;
123 | this.password = password;
124 | this.active = active;
125 | this.authorities = Stream
126 | .of(authorities)
127 | .map(SimpleGrantedAuthority::new)
128 | .collect(Collectors.toSet());
129 | }
130 |
131 | @Override
132 | public Collection extends GrantedAuthority> getAuthorities() {
133 | return this.authorities;
134 | }
135 |
136 | @Override
137 | public String getPassword() {
138 | return this.password;
139 | }
140 |
141 | @Override
142 | public String getUsername() {
143 | return this.username;
144 | }
145 |
146 | @Override
147 | public boolean isAccountNonExpired() {
148 | return this.active;
149 | }
150 |
151 | @Override
152 | public boolean isAccountNonLocked() {
153 | return this.active;
154 | }
155 |
156 | @Override
157 | public boolean isCredentialsNonExpired() {
158 | return this.active;
159 | }
160 |
161 | @Override
162 | public boolean isEnabled() {
163 | return this.active;
164 | }
165 | }
--------------------------------------------------------------------------------
/studio/password-encoding-and-migration/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | management.endpoints.web.exposure.include=*
2 |
--------------------------------------------------------------------------------
/studio/password-encoding-and-migration/src/test/java/com/example/customauthentication/CustomAuthenticationApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.customauthentication;
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 CustomAuthenticationApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/user-details/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | user-details
7 |
8 | livelessons
9 | authentication
10 | 0.0.1-SNAPSHOT
11 | ..
12 |
13 |
16 |
17 |
18 | org.springframework.boot
19 | spring-boot-starter-security
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-web
24 |
25 |
26 | com.h2database
27 | h2
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-jdbc
33 |
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-test
39 | test
40 |
41 |
42 | org.springframework.security
43 | spring-security-test
44 | test
45 |
46 |
47 |
48 |
49 |
50 | org.springframework.boot
51 | spring-boot-maven-plugin
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/user-details/src/main/java/livelessons/AuthenticationApplication.java:
--------------------------------------------------------------------------------
1 | package livelessons;
2 |
3 | import org.apache.commons.logging.Log;
4 | import org.apache.commons.logging.LogFactory;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.context.annotation.Profile;
10 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
11 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
12 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
13 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
14 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
15 | import org.springframework.security.crypto.password.LdapShaPasswordEncoder;
16 | import org.springframework.security.crypto.password.PasswordEncoder;
17 | import org.springframework.security.provisioning.InMemoryUserDetailsManager;
18 | import org.springframework.security.provisioning.JdbcUserDetailsManager;
19 | import org.springframework.security.provisioning.UserDetailsManager;
20 | import org.springframework.web.bind.annotation.GetMapping;
21 | import org.springframework.web.bind.annotation.RestController;
22 |
23 | import javax.sql.DataSource;
24 | import java.security.Principal;
25 |
26 | @SpringBootApplication
27 | public class AuthenticationApplication {
28 |
29 | private Log log = LogFactory.getLog(getClass());
30 |
31 | public static void main(String args[]) {
32 | SpringApplication.run(AuthenticationApplication.class, args);
33 | }
34 |
35 | @Bean
36 | PasswordEncoder passwordEncoder() {
37 | return PasswordEncoderFactories.createDelegatingPasswordEncoder();
38 | }
39 |
40 | @Bean
41 | @Profile("memory")
42 | UserDetailsManager memory() {
43 | log.info("starting the memory " + InMemoryUserDetailsManager.class.getName());
44 | return new InMemoryUserDetailsManager();
45 | }
46 |
47 | @Bean
48 | @Profile("jdbc")
49 | UserDetailsManager jdbc(DataSource ds) {
50 | log.info("starting the JDBC " + JdbcUserDetailsManager.class.getName());
51 | JdbcUserDetailsManager jdbc = new JdbcUserDetailsManager();
52 | jdbc.setDataSource(ds);
53 | return jdbc;
54 | }
55 |
56 | @Configuration
57 | @EnableWebSecurity
58 | public static class BasicAuthorizationConfig extends WebSecurityConfigurerAdapter {
59 |
60 | @Override
61 | protected void configure(HttpSecurity http) throws Exception {
62 | http.csrf().and().httpBasic().and().authorizeRequests().anyRequest()
63 | .authenticated();
64 | }
65 |
66 | }
67 |
68 | }
69 |
70 | @RestController
71 | class GreetingsRestController {
72 |
73 | @GetMapping("/greet")
74 | String greet(Principal p) {
75 | return "hello, " + p.getName() + "!";
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/user-details/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/user-details/src/main/resources/application.properties
--------------------------------------------------------------------------------
/user-details/src/main/resources/schema.sql:
--------------------------------------------------------------------------------
1 | drop table if exists users;
2 |
3 | create table users (
4 | username varchar_ignorecase(50) not null primary key,
5 | password varchar_ignorecase(500) not null,
6 | enabled boolean not null
7 | );
8 |
9 |
10 | drop table if exists authorities;
11 | create table authorities (
12 | username varchar_ignorecase(50) not null,
13 | authority varchar_ignorecase(50) not null,
14 | constraint fk_authorities_USERS foreign key (username) references users (username)
15 | );
16 | create unique index ix_auth_username
17 | on authorities (username, authority);
--------------------------------------------------------------------------------
/user-details/src/test/java/livelessons/JdbcUserDetailsServiceTest.java:
--------------------------------------------------------------------------------
1 | package livelessons;
2 |
3 | import org.springframework.test.context.ActiveProfiles;
4 |
5 | @ActiveProfiles("jdbc")
6 | public class JdbcUserDetailsServiceTest extends UserDetailsServiceTestBaseClass {
7 |
8 | }
--------------------------------------------------------------------------------
/user-details/src/test/java/livelessons/MemoryUserDetailsServiceTest.java:
--------------------------------------------------------------------------------
1 | package livelessons;
2 |
3 | import org.springframework.test.context.ActiveProfiles;
4 |
5 | /**
6 | * @author Josh Long
7 | */
8 | @ActiveProfiles("memory")
9 | public class MemoryUserDetailsServiceTest extends UserDetailsServiceTestBaseClass {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/user-details/src/test/java/livelessons/SimpleUserDetailsServiceTest.java:
--------------------------------------------------------------------------------
1 | package livelessons;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
6 | import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
7 | import org.springframework.security.core.Authentication;
8 | import org.springframework.security.core.authority.AuthorityUtils;
9 | import org.springframework.security.core.userdetails.User;
10 | import org.springframework.security.core.userdetails.UserDetails;
11 | import org.springframework.security.core.userdetails.UserDetailsService;
12 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
13 | import org.springframework.security.crypto.factory.PasswordEncoderFactories;
14 | import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
15 | import org.springframework.security.crypto.password.PasswordEncoder;
16 | import org.springframework.security.provisioning.InMemoryUserDetailsManager;
17 | import org.springframework.security.util.FieldUtils;
18 |
19 | import java.lang.reflect.Field;
20 | import java.util.Collection;
21 | import java.util.Map;
22 | import java.util.stream.Collectors;
23 | import java.util.stream.IntStream;
24 |
25 | public class SimpleUserDetailsServiceTest {
26 |
27 | private final PasswordEncoder passwordEncoder = PasswordEncoderFactories
28 | .createDelegatingPasswordEncoder();
29 |
30 | private final UserDetailsService userDetailsService = new InMemoryUserDetailsManager(
31 | this.contributeUsers());
32 |
33 | private final DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider() {
34 | {
35 | setPasswordEncoder(passwordEncoder);
36 | setUserDetailsService(userDetailsService);
37 | }
38 | };
39 |
40 | @Test
41 | @SuppressWarnings("unchecked")
42 | public void encode() throws Exception {
43 | String encodedPassword = this.passwordEncoder.encode("password");
44 | Assert.assertTrue(this.passwordEncoder.matches("password", encodedPassword));
45 |
46 | // is the ID in the encoded PW?
47 | Field idForEncode = fieldFor(DelegatingPasswordEncoder.class, "idForEncode");
48 | String id = String.class.cast(idForEncode.get(this.passwordEncoder));
49 | Assert.assertTrue(encodedPassword.contains(id));
50 |
51 | // is the default PasswordEncoder BCrypt?
52 | Field pwEncoderMapField = fieldFor(DelegatingPasswordEncoder.class,
53 | "idToPasswordEncoder");
54 | Map pwEncoderMap = (Map) pwEncoderMapField
55 | .get(this.passwordEncoder);
56 | Assert.assertTrue(pwEncoderMap.get(id) instanceof BCryptPasswordEncoder);
57 | }
58 |
59 | @Test
60 | public void loadUserByUsername() {
61 | UserDetails userDetails = this.userDetailsService.loadUserByUsername("user1");
62 | Assert.assertNotNull(userDetails);
63 | }
64 |
65 | @Test
66 | public void authenticate() {
67 | Authentication authentication = new UsernamePasswordAuthenticationToken("user1",
68 | "password1");
69 | Authentication result = this.daoAuthenticationProvider
70 | .authenticate(authentication);
71 | Assert.assertTrue(result.isAuthenticated());
72 | }
73 |
74 | private Collection contributeUsers() {
75 | return IntStream.range(0, 5)
76 | .mapToObj(i -> new User("user" + i,
77 | this.passwordEncoder.encode("password" + i), true, true, true,
78 | true, AuthorityUtils.createAuthorityList("USER")))
79 | .collect(Collectors.toList());
80 | }
81 |
82 | private Field fieldFor(Class> aClass, String fieldName) {
83 | Field idForEncode = FieldUtils.getField(aClass, fieldName);
84 | idForEncode.setAccessible(true);
85 | return idForEncode;
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/user-details/src/test/java/livelessons/UserDetailsServiceTestBaseClass.java:
--------------------------------------------------------------------------------
1 | package livelessons;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.context.event.ApplicationReadyEvent;
8 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
9 | import org.springframework.boot.test.context.SpringBootTest;
10 | import org.springframework.context.ApplicationListener;
11 | import org.springframework.context.annotation.Configuration;
12 | import org.springframework.context.annotation.Profile;
13 | import org.springframework.security.core.authority.AuthorityUtils;
14 | import org.springframework.security.core.userdetails.User;
15 | import org.springframework.security.core.userdetails.UserDetails;
16 | import org.springframework.security.crypto.password.PasswordEncoder;
17 | import org.springframework.security.provisioning.UserDetailsManager;
18 | import org.springframework.security.test.context.support.WithMockUser;
19 | import org.springframework.test.context.junit4.SpringRunner;
20 | import org.springframework.test.web.servlet.MockMvc;
21 |
22 | import java.util.Collection;
23 | import java.util.function.Consumer;
24 | import java.util.stream.Collectors;
25 | import java.util.stream.IntStream;
26 |
27 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
28 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
29 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
30 |
31 | @SpringBootTest
32 | @AutoConfigureMockMvc
33 | @RunWith(SpringRunner.class)
34 | public class UserDetailsServiceTestBaseClass {
35 |
36 | private final static String USERNAME = "user1";
37 |
38 | @Autowired
39 | private UserDetailsManager userDetailsManager;
40 |
41 | @Autowired
42 | private MockMvc mvc;
43 |
44 | @Test
45 | @WithMockUser(USERNAME)
46 | public void authenticate() throws Exception {
47 |
48 | String expectedString = String.format("hello, %s!", USERNAME);
49 |
50 | this.mvc.perform(get("/greet")).andExpect(status().isOk())
51 | .andExpect(content().string(expectedString));
52 | }
53 |
54 | @Test
55 | public void loadUserByUsername() {
56 | UserDetails user = this.userDetailsManager.loadUserByUsername("user1");
57 | Assert.assertNotNull(user);
58 | }
59 |
60 | @Test
61 | public void createUser() {
62 | String user = "user";
63 |
64 | this.userDetailsManager.deleteUser(user);
65 |
66 | UserDetails jane = User.withDefaultPasswordEncoder().username(user).password("pw")
67 | .roles("USER").build();
68 | this.userDetailsManager.createUser(jane);
69 | Assert.assertTrue(this.userDetailsManager.userExists(jane.getUsername()));
70 | }
71 |
72 | }
73 |
74 | @Configuration
75 | @Profile("!ldap")
76 | class Initializer implements ApplicationListener {
77 |
78 | private final PasswordEncoder passwordEncoder;
79 |
80 | private final UserDetailsManager userDetailsManager;
81 |
82 | Initializer(PasswordEncoder passwordEncoder, UserDetailsManager userDetailsManager) {
83 | this.passwordEncoder = passwordEncoder;
84 | this.userDetailsManager = userDetailsManager;
85 | }
86 |
87 | @Override
88 | public void onApplicationEvent(ApplicationReadyEvent evt) {
89 | Consumer process = user -> {
90 | this.userDetailsManager.deleteUser(user.getUsername());
91 | this.userDetailsManager.createUser(user);
92 | };
93 |
94 | Collection userDetails = IntStream.range(0, 5)
95 | .mapToObj(i -> new User("user" + i,
96 | this.passwordEncoder.encode("password" + i), true, true, true,
97 | true, AuthorityUtils.createAuthorityList("USER")))
98 | .collect(Collectors.toList());
99 |
100 | userDetails.forEach(process);
101 | }
102 |
103 | }
--------------------------------------------------------------------------------
/xauth-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | livelessons
7 | authentication
8 | 0.0.1-SNAPSHOT
9 | ..
10 |
11 | xauth-app
12 |
13 |
14 | org.springframework.boot
15 | spring-boot-starter-security
16 |
17 |
18 | org.springframework.boot
19 | spring-boot-starter-web
20 |
21 |
22 | livelessons
23 | xauth
24 | 0.0.1-SNAPSHOT
25 |
26 |
27 | org.projectlombok
28 | lombok
29 | true
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-test
34 | test
35 |
36 |
37 | org.springframework.security
38 | spring-security-test
39 | test
40 |
41 |
42 |
43 |
44 |
45 | org.springframework.boot
46 | spring-boot-maven-plugin
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/xauth-app/src/main/java/livelessons/custom/CustomApplication.java:
--------------------------------------------------------------------------------
1 | package livelessons.custom;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.core.Ordered;
8 | import org.springframework.core.annotation.Order;
9 | import org.springframework.security.authentication.AuthenticationManager;
10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
12 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
13 | import org.springframework.security.core.userdetails.User;
14 | import org.springframework.security.core.userdetails.UserDetails;
15 | import org.springframework.security.provisioning.InMemoryUserDetailsManager;
16 | import org.springframework.web.bind.annotation.GetMapping;
17 | import org.springframework.web.bind.annotation.RestController;
18 |
19 | import java.security.Principal;
20 |
21 | /**
22 | * curl -v -X POST -F "username=rob" -F"password=pw" http://localhost:8080/authenticate
23 | * curl -v -H"x-auth-token: rob:1532068547605:c704d3c1c78a17922070a8e7b7e02144"
24 | * http://localhost:8080/greet
25 | */
26 | @SpringBootApplication
27 | public class CustomApplication {
28 |
29 | public static void main(String[] args) {
30 | SpringApplication.run(CustomApplication.class, args);
31 | }
32 |
33 | }
34 |
35 | @Configuration
36 | class UserConfiguration {
37 |
38 | @Bean
39 | InMemoryUserDetailsManager authentication() {
40 | return new InMemoryUserDetailsManager(user("rob"), user("josh"));
41 | }
42 |
43 | private static UserDetails user(String u) {
44 | return User.withDefaultPasswordEncoder().roles("USER").username(u).password("pw")
45 | .build();
46 | }
47 |
48 | }
49 |
50 | @Configuration
51 | @EnableWebSecurity
52 | class CustomSecurity extends WebSecurityConfigurerAdapter {
53 |
54 | @Bean
55 | @Override
56 | public AuthenticationManager authenticationManagerBean() throws Exception {
57 | return super.authenticationManagerBean();
58 | }
59 |
60 | @Override
61 | protected void configure(HttpSecurity http) throws Exception {
62 |
63 | http.authorizeRequests().mvcMatchers("/greet").authenticated().anyRequest()
64 | .permitAll().and().httpBasic().and().csrf().disable();
65 | }
66 |
67 | }
68 |
69 | @RestController
70 | class GreetingsRestController {
71 |
72 | @GetMapping("/greet")
73 | String greet(Principal p) {
74 | return "hello, " + p.getName() + "!";
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/xauth-app/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-security-livelessons/authentication/238681ae99079652113fff69426783f7db864f03/xauth-app/src/main/resources/application.properties
--------------------------------------------------------------------------------
/xauth-app/src/test/java/livelessons/custom/GreetingsRestControllerTest.java:
--------------------------------------------------------------------------------
1 | package livelessons.custom;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.junit.Assert;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
12 | import org.springframework.boot.test.context.SpringBootTest;
13 | import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
14 | import org.springframework.test.context.junit4.SpringRunner;
15 | import org.springframework.test.web.servlet.MockMvc;
16 | import org.springframework.test.web.servlet.setup.MockMvcBuilders;
17 | import org.springframework.web.context.WebApplicationContext;
18 |
19 | import java.util.Map;
20 | import java.util.concurrent.atomic.AtomicReference;
21 |
22 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.anonymous;
23 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
24 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
25 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
26 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
27 |
28 | @Slf4j
29 | @RunWith(SpringRunner.class)
30 | @SpringBootTest
31 | @AutoConfigureMockMvc
32 | public class GreetingsRestControllerTest {
33 |
34 | @Autowired
35 | private ObjectMapper objectMapper;
36 |
37 | @Autowired
38 | private WebApplicationContext context;
39 |
40 | private MockMvc mvc;
41 |
42 | @Before
43 | public void setup() {
44 | this.mvc = MockMvcBuilders.webAppContextSetup(this.context)
45 | .apply(SecurityMockMvcConfigurers.springSecurity()).build();
46 | }
47 |
48 | @Test
49 | public void greetFail() throws Exception {
50 |
51 | this.mvc.perform(get("/greet").with(anonymous()))
52 | .andExpect(status().is4xxClientError());
53 | }
54 |
55 | @Test
56 | public void greetSuccess() throws Exception {
57 |
58 | TypeReference