Added second version to authenticate with client certificates.

This commit is contained in:
Christian Rädel 2016-08-08 01:55:42 +02:00
parent 8dc92aa09c
commit 3c76943627
11 changed files with 110 additions and 25 deletions

View File

@ -1,5 +1,6 @@
package com.baeldung.spring.security.x509; package com.baeldung.spring.security.x509;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -10,6 +11,7 @@ import java.security.Principal;
@Controller @Controller
public class UserController { public class UserController {
@PreAuthorize("hasAuthority('ROLE_USER')")
@RequestMapping(value = "/user") @RequestMapping(value = "/user")
public String user(Model model, Principal principal) { public String user(Model model, Principal principal) {
UserDetails currentUser = (UserDetails) ((Authentication) principal).getPrincipal(); UserDetails currentUser = (UserDetails) ((Authentication) principal).getPrincipal();

View File

@ -1,11 +1,48 @@
package com.baeldung.spring.security.x509; package com.baeldung.spring.security.x509;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@SpringBootApplication @SpringBootApplication
public class X509AuthenticationServer { @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class X509AuthenticationServer extends WebSecurityConfigurerAdapter {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(X509AuthenticationServer.class, args); SpringApplication.run(X509AuthenticationServer.class, args);
} }
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and()
.x509().subjectPrincipalRegex("CN=(.*?)(?:,|$)").userDetailsService(userDetailsService());
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username.equals("cid")) {
return new User(username, "", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
}
throw new UsernameNotFoundException("User not found!");
}
};
}
} }

View File

@ -6,3 +6,6 @@ server.ssl.enabled=true
server.port=8443 server.port=8443
security.user.name=Admin security.user.name=Admin
security.user.password=admin security.user.password=admin
server.ssl.trust-store=../keystore/truststore.jks
server.ssl.trust-store-password=${PASSWORD}
server.ssl.client-auth=need

View File

@ -4,12 +4,12 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.spring.security</groupId> <groupId>com.baeldung.spring.security</groupId>
<artifactId>server</artifactId> <artifactId>client-auth-server</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>server</name> <name>client-auth-server</name>
<description>Spring x.509 Authentication Demo</description> <description>Spring x.509 Client Authentication Demo</description>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -1,5 +1,6 @@
package com.baeldung.spring.security.x509; package com.baeldung.spring.security.x509;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -9,8 +10,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import java.security.Principal; import java.security.Principal;
@Controller @Controller
public class UserResource { public class UserController {
@PreAuthorize("hasAuthority('ROLE_USER')")
@RequestMapping(value = "/user") @RequestMapping(value = "/user")
public String user(Model model, Principal principal) { public String user(Model model, Principal principal) {
UserDetails currentUser = (UserDetails) ((Authentication) principal).getPrincipal(); UserDetails currentUser = (UserDetails) ((Authentication) principal).getPrincipal();

View File

@ -0,0 +1,47 @@
package com.baeldung.spring.security.x509;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@SpringBootApplication
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class X509AuthenticationServer extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(X509AuthenticationServer.class, args);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and()
.x509().subjectPrincipalRegex("CN=(.*?)(?:,|$)").userDetailsService(userDetailsService());
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username.equals("cid")) {
return new User(username, "", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
}
throw new UsernameNotFoundException("User not found!");
}
};
}
}

View File

@ -1,8 +1,11 @@
server.ssl.key-store=../keystore/keystore.jks server.ssl.key-store=../keystore/keystore.jks
server.ssl.key-store-password=${PASSWORD} server.ssl.key-store-password=${PASSWORD}
server.ssl.key-alias=localhost server.ssl.key-alias=${HOSTNAME}
server.ssl.key-password=${PASSWORD} server.ssl.key-password=${PASSWORD}
server.ssl.enabled=true server.ssl.enabled=true
server.port=8443 server.port=8443
security.user.name=Admin security.user.name=Admin
security.user.password=admin security.user.password=admin
server.ssl.trust-store=../keystore/truststore.jks
server.ssl.trust-store-password=${PASSWORD}
server.ssl.client-auth=need

View File

@ -1,9 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"> <html xmlns:th="http://www.thymeleaf.org">
<head> <head>
<title>X.509 Authentication Demo</title> <title>X.509 Authentication Demo</title>
</head> </head>
<body> <body>
<h2>Hello <span th:text="${username}"/>!</h2> <h2>Hello <span th:text="${username}"/>!</h2>
</body> </body>
</html> </html>

View File

@ -8,9 +8,7 @@ import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest @SpringBootTest
public class X509AuthenticationServerTests { public class X509AuthenticationServerTests {
@Test @Test
public void contextLoads() { public void contextLoads() {
} }
} }

View File

@ -2,6 +2,7 @@ PASSWORD=changeit
KEYSTORE=keystore.jks KEYSTORE=keystore.jks
HOSTNAME=localhost HOSTNAME=localhost
CLIENTNAME=cid CLIENTNAME=cid
# CN = Common Name # CN = Common Name
# OU = Organization Unit # OU = Organization Unit
# O = Organization Name # O = Organization Name
@ -76,6 +77,11 @@ add-client:
keytool -import -trustcacerts -alias $(CLIENTNAME) \ keytool -import -trustcacerts -alias $(CLIENTNAME) \
-file "$(CLIENTNAME).crt" \ -file "$(CLIENTNAME).crt" \
-keystore $(TRUSTSTORE) -storepass $(PASSWORD) -keystore $(TRUSTSTORE) -storepass $(PASSWORD)
# Export private certificate for importing into a browser
keytool -importkeystore -srcalias $(CLIENTNAME) \
-srckeystore $(TRUSTSTORE) -srcstorepass $(PASSWORD) \
-destkeystore "$(CLIENTNAME).p12" -deststorepass $(PASSWORD) \
-deststoretype PKCS12
clean: clean:
# Remove generated artifacts # Remove generated artifacts

View File

@ -1,12 +0,0 @@
package com.baeldung.spring.security.x509;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class X509AuthenticationServer {
public static void main(String[] args) {
SpringApplication.run(X509AuthenticationServer.class, args);
}
}