Java Brains Spring Security
Adding Spring Secutry to new spring boot project
How to configure spring security authentication
How to configure spring security authorization
src/main/java/io/javabrains/springbootsecurity/HomeResource.java
package io .javabrains .springbootsecurity ;
import org .springframework .web .bind .annotation .GetMapping ;
import org .springframework .web .bind .annotation .RestController ;
@ RestController
public class HomeResource {
@ GetMapping ("/" )
public String home () {
return ("<h1>Welcome</h1>" );
}
@ GetMapping ("/user" )
public String user () {
return ("<h1>Welcome User</h1>" );
}
@ GetMapping ("/admin" )
public String admin () {
return ("<h1>Welcome Admin</h1>" );
}
}
src/main/java/io/javabrains/springbootsecurity/SecurityConfiguration.java
package io .javabrains .springbootsecurity ;
import org .springframework .context .annotation .Bean ;
import org .springframework .security .config .annotation .authentication .builders .AuthenticationManagerBuilder ;
import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
import org .springframework .security .config .annotation .web .configuration .WebSecurityConfigurerAdapter ;
import org .springframework .security .crypto .password .NoOpPasswordEncoder ;
import org .springframework .security .crypto .password .PasswordEncoder ;
@ EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@ Override
protected void configure (AuthenticationManagerBuilder auth ) throws Exception {
// Set your configuration on the auth object
auth .inMemoryAuthentication ()
.withUser ("blah" )
.password ("blah" )
.roles ("USER" )
.and ()
.withUser ("foo" )
.password ("foo" )
.roles ("ADMIN" );
}
@ Bean
public PasswordEncoder getPasswordEncoder () {
return NoOpPasswordEncoder .getInstance ();
}
@ Override
protected void configure (HttpSecurity http ) throws Exception {
http .authorizeRequests ()
.antMatchers ("/admin" ).hasRole ("ADMIN" )
.antMatchers ("/user" ).hasAnyRole ("ADMIN" , "USER" )
.antMatchers ("/" ).permitAll ()
.and ().formLogin ();
}
}
How Spring security works
Spring Boot + Spring Security + JPA authentication and MySql
/src/main/resources/application.properties
spring.datasource.url =jdbc:mysql://localhost:3306/springsecurity
spring.datasource.username =root
spring.datasource.password =password
spring.jpa.hibernate.ddl-auto =update
spring.jpa.hibernate.naming-strategy =org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect =org.hibernate.dialect.MySQL5Dialect
src/main/java/io/javabrains/springsecurityjpa/models/MyUserDetails.java
package io .javabrains .springsecurityjpa .models ;
import org .springframework .security .core .GrantedAuthority ;
import org .springframework .security .core .authority .SimpleGrantedAuthority ;
import org .springframework .security .core .userdetails .UserDetails ;
import java .util .Arrays ;
import java .util .Collection ;
import java .util .List ;
import java .util .stream .Collectors ;
public class MyUserDetails implements UserDetails {
private String userName ;
private String password ;
private boolean active ;
private List <GrantedAuthority > authorities ;
public MyUserDetails (User user ) {
this .userName = user .getUserName ();
this .password = user .getPassword ();
this .active = user .isActive ();
this .authorities = Arrays .stream (user .getRoles ().split ("," ))
.map (SimpleGrantedAuthority ::new )
.collect (Collectors .toList ());
}
@ Override
public Collection <? extends GrantedAuthority > getAuthorities () {
return authorities ;
}
@ Override
public String getPassword () {
return password ;
}
@ Override
public String getUsername () {
return userName ;
}
@ Override
public boolean isAccountNonExpired () {
return true ;
}
@ Override
public boolean isAccountNonLocked () {
return true ;
}
@ Override
public boolean isCredentialsNonExpired () {
return true ;
}
@ Override
public boolean isEnabled () {
return active ;
}
}
/src/main/java/io/javabrains/springsecurityjpa/models/User.java
package io .javabrains .springsecurityjpa .models ;
import javax .persistence .*;
@ Entity
@ Table (name = "User" )
public class User {
@ Id
@ GeneratedValue (strategy = GenerationType .AUTO )
private int id ;
private String userName ;
private String password ;
private boolean active ;
private String roles ;
public int getId () {
return id ;
}
public void setId (int id ) {
this .id = id ;
}
public String getUserName () {
return userName ;
}
public void setUserName (String userName ) {
this .userName = userName ;
}
public String getPassword () {
return password ;
}
public void setPassword (String password ) {
this .password = password ;
}
public boolean isActive () {
return active ;
}
public void setActive (boolean active ) {
this .active = active ;
}
public String getRoles () {
return roles ;
}
public void setRoles (String roles ) {
this .roles = roles ;
}
}
/src/main/java/io/javabrains/springsecurityjpa/HomeResource.java
package io .javabrains .springsecurityjpa ;
import org .springframework .web .bind .annotation .GetMapping ;
import org .springframework .web .bind .annotation .RestController ;
@ RestController
public class HomeResource {
@ GetMapping ("/" )
public String home () {
return ("<h1>Welcome</h1>" );
}
@ GetMapping ("/user" )
public String user () {
return ("<h1>Welcome User</h1>" );
}
@ GetMapping ("/admin" )
public String admin () {
return ("<h1>Welcome Admin</h1>" );
}
}
/src/main/java/io/javabrains/springsecurityjpa/MyUserDetailsService.java
package io .javabrains .springsecurityjpa ;
import io .javabrains .springsecurityjpa .models .MyUserDetails ;
import io .javabrains .springsecurityjpa .models .User ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .security .core .userdetails .UserDetails ;
import org .springframework .security .core .userdetails .UserDetailsService ;
import org .springframework .security .core .userdetails .UsernameNotFoundException ;
import org .springframework .stereotype .Service ;
import java .util .Optional ;
@ Service
public class MyUserDetailsService implements UserDetailsService {
@ Autowired
UserRepository userRepository ;
@ Override
public UserDetails loadUserByUsername (String userName ) throws UsernameNotFoundException {
Optional <User > user = userRepository .findByUserName (userName );
user .orElseThrow (() -> new UsernameNotFoundException ("Not found: " + userName ));
return user .map (MyUserDetails ::new ).get ();
}
}
/src/main/java/io/javabrains/springsecurityjpa/SecurityConfiguration.java
package io .javabrains .springsecurityjpa ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .context .annotation .Bean ;
import org .springframework .security .config .annotation .authentication .builders .AuthenticationManagerBuilder ;
import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
import org .springframework .security .config .annotation .web .configuration .WebSecurityConfigurerAdapter ;
import org .springframework .security .core .userdetails .UserDetailsService ;
import org .springframework .security .crypto .password .NoOpPasswordEncoder ;
import org .springframework .security .crypto .password .PasswordEncoder ;
@ EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@ Autowired
UserDetailsService userDetailsService ;
@ Override
protected void configure (AuthenticationManagerBuilder auth ) throws Exception {
auth .userDetailsService (userDetailsService );
}
@ Override
protected void configure (HttpSecurity http ) throws Exception {
http .authorizeRequests ()
.antMatchers ("/admin" ).hasRole ("ADMIN" )
.antMatchers ("/user" ).hasAnyRole ("ADMIN" , "USER" )
.antMatchers ("/" ).permitAll ()
.and ().formLogin ();
}
@ Bean
public PasswordEncoder getPasswordEncoder () {
return NoOpPasswordEncoder .getInstance ();
}
}
/src/main/java/io/javabrains/springsecurityjpa/UserRepository.java
package io .javabrains .springsecurityjpa ;
import io .javabrains .springsecurityjpa .models .User ;
import org .springframework .data .jpa .repository .JpaRepository ;
import java .util .Optional ;
public interface UserRepository extends JpaRepository <User , Integer > {
Optional <User > findByUserName (String userName );
}
/src/main/java/io/javabrains/springsecurityjpa/SpringSecurityJpaApplication.java
package io .javabrains .springsecurityjpa ;
import org .springframework .boot .SpringApplication ;
import org .springframework .boot .autoconfigure .SpringBootApplication ;
import org .springframework .data .jpa .repository .config .EnableJpaRepositories ;
@ SpringBootApplication
@ EnableJpaRepositories (basePackageClasses = UserRepository .class )
public class SpringSecurityJpaApplication {
public static void main (String [] args ) {
SpringApplication .run (SpringSecurityJpaApplication .class , args );
}
}
Spring Boot + Spring Security + LDAP
Spring Boot+ Spring Security + JWT
/src/main/java/io/javabrains/springsecurityjwt/SpringSecurityJwtApplication.java
package io .javabrains .springsecurityjwt ;
import io .javabrains .springsecurityjwt .filters .JwtRequestFilter ;
import io .javabrains .springsecurityjwt .models .AuthenticationRequest ;
import io .javabrains .springsecurityjwt .models .AuthenticationResponse ;
import io .javabrains .springsecurityjwt .util .JwtUtil ;
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 .http .ResponseEntity ;
import org .springframework .security .authentication .AuthenticationManager ;
import org .springframework .security .authentication .BadCredentialsException ;
import org .springframework .security .authentication .UsernamePasswordAuthenticationToken ;
import org .springframework .security .config .annotation .authentication .builders .AuthenticationManagerBuilder ;
import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
import org .springframework .security .config .annotation .web .configuration .WebSecurityConfigurerAdapter ;
import org .springframework .security .config .http .SessionCreationPolicy ;
import org .springframework .security .core .userdetails .UserDetails ;
import org .springframework .security .core .userdetails .UserDetailsService ;
import org .springframework .security .crypto .password .NoOpPasswordEncoder ;
import org .springframework .security .crypto .password .PasswordEncoder ;
import org .springframework .security .web .authentication .UsernamePasswordAuthenticationFilter ;
import org .springframework .web .bind .annotation .RequestBody ;
import org .springframework .web .bind .annotation .RequestMapping ;
import org .springframework .web .bind .annotation .RequestMethod ;
import org .springframework .web .bind .annotation .RestController ;
@ SpringBootApplication
public class SpringSecurityJwtApplication {
public static void main (String [] args ) {
SpringApplication .run (SpringSecurityJwtApplication .class , args );
}
}
@ RestController
class HelloWorldController {
@ Autowired
private AuthenticationManager authenticationManager ;
@ Autowired
private JwtUtil jwtTokenUtil ;
@ Autowired
private MyUserDetailsService userDetailsService ;
@ RequestMapping ({ "/hello" })
public String firstPage () {
return "Hello World" ;
}
@ RequestMapping (value = "/authenticate" , method = RequestMethod .POST )
public ResponseEntity <?> createAuthenticationToken (@ RequestBody AuthenticationRequest authenticationRequest ) throws Exception {
try {
authenticationManager .authenticate (
new UsernamePasswordAuthenticationToken (authenticationRequest .getUsername (), authenticationRequest .getPassword ())
);
}
catch (BadCredentialsException e ) {
throw new Exception ("Incorrect username or password" , e );
}
final UserDetails userDetails = userDetailsService
.loadUserByUsername (authenticationRequest .getUsername ());
final String jwt = jwtTokenUtil .generateToken (userDetails );
return ResponseEntity .ok (new AuthenticationResponse (jwt ));
}
}
@ EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@ Autowired
private UserDetailsService myUserDetailsService ;
@ Autowired
private JwtRequestFilter jwtRequestFilter ;
@ Autowired
public void configureGlobal (AuthenticationManagerBuilder auth ) throws Exception {
auth .userDetailsService (myUserDetailsService );
}
@ Bean
public PasswordEncoder passwordEncoder () {
return NoOpPasswordEncoder .getInstance ();
}
@ Override
@ Bean
public AuthenticationManager authenticationManagerBean () throws Exception {
return super .authenticationManagerBean ();
}
@ Override
protected void configure (HttpSecurity httpSecurity ) throws Exception {
httpSecurity .csrf ().disable ()
.authorizeRequests ().antMatchers ("/authenticate" ).permitAll ().
anyRequest ().authenticated ().and ().
exceptionHandling ().and ().sessionManagement ()
.sessionCreationPolicy (SessionCreationPolicy .STATELESS );
httpSecurity .addFilterBefore (jwtRequestFilter , UsernamePasswordAuthenticationFilter .class );
}
}
/src/main/java/io/javabrains/springsecurityjwt/MyUserDetailsService.java
package io .javabrains .springsecurityjwt ;
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 ;
import org .springframework .stereotype .Service ;
import java .util .ArrayList ;
@ Service
public class MyUserDetailsService implements UserDetailsService {
@ Override
public UserDetails loadUserByUsername (String s ) throws UsernameNotFoundException {
return new User ("foo" , "foo" ,
new ArrayList <>());
}
}
/src/main/java/io/javabrains/springsecurityjwt/util/JwtUtil.java
package io .javabrains .springsecurityjwt .util ;
import io .jsonwebtoken .Claims ;
import io .jsonwebtoken .Jwts ;
import io .jsonwebtoken .SignatureAlgorithm ;
import org .springframework .security .core .userdetails .UserDetails ;
import org .springframework .stereotype .Service ;
import java .util .Date ;
import java .util .HashMap ;
import java .util .Map ;
import java .util .function .Function ;
@ Service
public class JwtUtil {
private String SECRET_KEY = "secret" ;
public String extractUsername (String token ) {
return extractClaim (token , Claims ::getSubject );
}
public Date extractExpiration (String token ) {
return extractClaim (token , Claims ::getExpiration );
}
public <T > T extractClaim (String token , Function <Claims , T > claimsResolver ) {
final Claims claims = extractAllClaims (token );
return claimsResolver .apply (claims );
}
private Claims extractAllClaims (String token ) {
return Jwts .parser ().setSigningKey (SECRET_KEY ).parseClaimsJws (token ).getBody ();
}
private Boolean isTokenExpired (String token ) {
return extractExpiration (token ).before (new Date ());
}
public String generateToken (UserDetails userDetails ) {
Map <String , Object > claims = new HashMap <>();
return createToken (claims , userDetails .getUsername ());
}
private String createToken (Map <String , Object > claims , String subject ) {
return Jwts .builder ().setClaims (claims ).setSubject (subject ).setIssuedAt (new Date (System .currentTimeMillis ()))
.setExpiration (new Date (System .currentTimeMillis () + 1000 * 60 * 60 * 10 ))
.signWith (SignatureAlgorithm .HS256 , SECRET_KEY ).compact ();
}
public Boolean validateToken (String token , UserDetails userDetails ) {
final String username = extractUsername (token );
return (username .equals (userDetails .getUsername ()) && !isTokenExpired (token ));
}
}
/src/main/java/io/javabrains/springsecurityjwt/models/AuthenticationRequest.java
package io .javabrains .springsecurityjwt .models ;
import java .io .Serializable ;
public class AuthenticationRequest implements Serializable {
private String username ;
private String password ;
public String getUsername () {
return username ;
}
public void setUsername (String username ) {
this .username = username ;
}
public String getPassword () {
return password ;
}
public void setPassword (String password ) {
this .password = password ;
}
//need default constructor for JSON Parsing
public AuthenticationRequest ()
{
}
public AuthenticationRequest (String username , String password ) {
this .setUsername (username );
this .setPassword (password );
}
}
/src/main/java/io/javabrains/springsecurityjwt/models/AuthenticationResponse.java
package io .javabrains .springsecurityjwt .models ;
import java .io .Serializable ;
public class AuthenticationResponse implements Serializable {
private final String jwt ;
public AuthenticationResponse (String jwt ) {
this .jwt = jwt ;
}
public String getJwt () {
return jwt ;
}
}
/src/main/java/io/javabrains/springsecurityjwt/filters/JwtRequestFilter.java
package io .javabrains .springsecurityjwt .filters ;
import io .javabrains .springsecurityjwt .MyUserDetailsService ;
import io .javabrains .springsecurityjwt .util .JwtUtil ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .security .authentication .UsernamePasswordAuthenticationToken ;
import org .springframework .security .core .context .SecurityContextHolder ;
import org .springframework .security .core .userdetails .UserDetails ;
import org .springframework .security .web .authentication .WebAuthenticationDetailsSource ;
import org .springframework .stereotype .Component ;
import org .springframework .web .filter .OncePerRequestFilter ;
import javax .servlet .FilterChain ;
import javax .servlet .ServletException ;
import javax .servlet .http .HttpServletRequest ;
import javax .servlet .http .HttpServletResponse ;
import java .io .IOException ;
@ Component
public class JwtRequestFilter extends OncePerRequestFilter {
@ Autowired
private MyUserDetailsService userDetailsService ;
@ Autowired
private JwtUtil jwtUtil ;
@ Override
protected void doFilterInternal (HttpServletRequest request , HttpServletResponse response , FilterChain chain )
throws ServletException , IOException {
final String authorizationHeader = request .getHeader ("Authorization" );
String username = null ;
String jwt = null ;
if (authorizationHeader != null && authorizationHeader .startsWith ("Bearer " )) {
jwt = authorizationHeader .substring (7 );
username = jwtUtil .extractUsername (jwt );
}
if (username != null && SecurityContextHolder .getContext ().getAuthentication () == null ) {
UserDetails userDetails = this .userDetailsService .loadUserByUsername (username );
if (jwtUtil .validateToken (jwt , userDetails )) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken (
userDetails , null , userDetails .getAuthorities ());
usernamePasswordAuthenticationToken
.setDetails (new WebAuthenticationDetailsSource ().buildDetails (request ));
SecurityContextHolder .getContext ().setAuthentication (usernamePasswordAuthenticationToken );
}
}
chain .doFilter (request , response );
}
}
Implementing login with Facebook and Github
Spring Security using Spring Data JPA + MySQL + Spring Boot | Java Techie