import source BAEL-1084 (#2560)
This commit is contained in:
parent
fd37ffb7c2
commit
0d599aeca1
@ -0,0 +1,38 @@
|
|||||||
|
package org.baeldung.rolesauthorities;
|
||||||
|
|
||||||
|
import org.baeldung.rolesauthorities.model.User;
|
||||||
|
import org.baeldung.rolesauthorities.persistence.UserRepository;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
|
||||||
|
public class CustomAuthenticationProvider extends DaoAuthenticationProvider {
|
||||||
|
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private UserDetailsService userDetailsService;
|
||||||
|
|
||||||
|
public CustomAuthenticationProvider(UserRepository userRepository, UserDetailsService userDetailsService){
|
||||||
|
super();
|
||||||
|
this.setUserDetailsService(userDetailsService);
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authentication authenticate(Authentication auth) throws AuthenticationException {
|
||||||
|
final User user = userRepository.findByEmail(auth.getName());
|
||||||
|
if ((user == null)) {
|
||||||
|
throw new BadCredentialsException("Invalid username or password");
|
||||||
|
}
|
||||||
|
final Authentication result = super.authenticate(auth);
|
||||||
|
return new UsernamePasswordAuthenticationToken(user, result.getCredentials(), result.getAuthorities());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(Class<?> authentication) {
|
||||||
|
return authentication.equals(UsernamePasswordAuthenticationToken.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package org.baeldung.rolesauthorities;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component("myLogoutSuccessHandler")
|
||||||
|
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
|
||||||
|
final HttpSession session = request.getSession();
|
||||||
|
if (session != null) {
|
||||||
|
session.removeAttribute("user");
|
||||||
|
}
|
||||||
|
|
||||||
|
response.sendRedirect("/");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package org.baeldung.rolesauthorities;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.baeldung.rolesauthorities.model.Privilege;
|
||||||
|
import org.baeldung.rolesauthorities.model.Role;
|
||||||
|
import org.baeldung.rolesauthorities.model.User;
|
||||||
|
import org.baeldung.rolesauthorities.persistence.UserRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
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 org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service("userDetailsService")
|
||||||
|
@Transactional
|
||||||
|
public class MyUserDetailsService implements UserDetailsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
public MyUserDetailsService() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(final String email) throws UsernameNotFoundException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
final User user = userRepository.findByEmail(email);
|
||||||
|
if (user == null) {
|
||||||
|
throw new UsernameNotFoundException("No user found with username: " + email);
|
||||||
|
}
|
||||||
|
org.springframework.security.core.userdetails.User userDetails = new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), user.isEnabled(), true, true, true, getAuthorities(user.getRoles()));
|
||||||
|
return userDetails;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UTIL
|
||||||
|
|
||||||
|
private final Collection<? extends GrantedAuthority> getAuthorities(final Collection<Role> roles) {
|
||||||
|
final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
|
||||||
|
for (Role role: roles) {
|
||||||
|
authorities.add(new SimpleGrantedAuthority(role.getName()));
|
||||||
|
for (Privilege privilege: role.getPrivileges()) {
|
||||||
|
authorities.add(new SimpleGrantedAuthority(privilege.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return authorities;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package org.baeldung.rolesauthorities;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@ComponentScan("org.baeldung.rolesauthorities")
|
||||||
|
public class RolesAuthoritiesApplication extends SpringBootServletInitializer {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.setProperty("spring.profiles.default", "rolesauthorities");
|
||||||
|
SpringApplication.run(RolesAuthoritiesApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package org.baeldung.rolesauthorities.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||||
|
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
|
||||||
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
public class MvcConfig extends WebMvcConfigurerAdapter {
|
||||||
|
|
||||||
|
public MvcConfig() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
@Bean
|
||||||
|
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||||
|
return new PropertySourcesPlaceholderConfigurer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) {
|
||||||
|
configurer.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||||
|
super.addViewControllers(registry);
|
||||||
|
registry.addViewController("/").setViewName("forward:/home");
|
||||||
|
registry.addViewController("/protectedbynothing").setViewName("rolesauthorities/protectedbynothing");
|
||||||
|
registry.addViewController("/protectedbyrole").setViewName("rolesauthorities/protectedbyrole");
|
||||||
|
registry.addViewController("/protectedbyauthority").setViewName("rolesauthorities/protectedbyauthority");
|
||||||
|
registry.addViewController("/login").setViewName("rolesauthorities/login");
|
||||||
|
registry.addViewController("/home").setViewName("rolesauthorities/home");
|
||||||
|
registry.addViewController("/logout");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
|
||||||
|
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
package org.baeldung.rolesauthorities.config;
|
||||||
|
|
||||||
|
import org.baeldung.rolesauthorities.CustomAuthenticationProvider;
|
||||||
|
import org.baeldung.rolesauthorities.persistence.UserRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
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.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.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ComponentScan(basePackages = { "org.baeldung.rolesauthorities" })
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserDetailsService userDetailsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LogoutSuccessHandler myLogoutSuccessHandler;
|
||||||
|
|
||||||
|
public SecurityConfig() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
auth.authenticationProvider(authProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(final WebSecurity web) throws Exception {
|
||||||
|
web.ignoring()
|
||||||
|
.antMatchers("/resources/**");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(final HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
.csrf().disable()
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/login*", "/logout*", "/protectedbynothing*", "/home*").permitAll()
|
||||||
|
.antMatchers("/protectedbyrole").hasRole("USER")
|
||||||
|
.antMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE")
|
||||||
|
.and()
|
||||||
|
.formLogin()
|
||||||
|
.loginPage("/login")
|
||||||
|
.failureUrl("/login?error=true")
|
||||||
|
.permitAll()
|
||||||
|
.and()
|
||||||
|
.logout()
|
||||||
|
.logoutSuccessHandler(myLogoutSuccessHandler)
|
||||||
|
.invalidateHttpSession(false)
|
||||||
|
.logoutSuccessUrl("/logout.html?logSucc=true")
|
||||||
|
.deleteCookies("JSESSIONID")
|
||||||
|
.permitAll();
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
// beans
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DaoAuthenticationProvider authProvider() {
|
||||||
|
final CustomAuthenticationProvider authProvider
|
||||||
|
= new CustomAuthenticationProvider(userRepository, userDetailsService);
|
||||||
|
authProvider.setPasswordEncoder(encoder());
|
||||||
|
return authProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder encoder() {
|
||||||
|
return new BCryptPasswordEncoder(11);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package org.baeldung.rolesauthorities.model;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToMany;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Privilege {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy = "privileges")
|
||||||
|
private Collection<Role> roles;
|
||||||
|
|
||||||
|
public Privilege() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Privilege(final String name) {
|
||||||
|
super();
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Role> getRoles() {
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoles(final Collection<Role> roles) {
|
||||||
|
this.roles = roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Privilege other = (Privilege) obj;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Privilege [name=").append(name).append("]").append("[id=").append(id).append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package org.baeldung.rolesauthorities.model;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinTable;
|
||||||
|
import javax.persistence.ManyToMany;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Role {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy = "roles")
|
||||||
|
private Collection<User> users;
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "roles_privileges", joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id"))
|
||||||
|
private Collection<Privilege> privileges;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Role() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Role(final String name) {
|
||||||
|
super();
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<User> getUsers() {
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsers(final Collection<User> users) {
|
||||||
|
this.users = users;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Privilege> getPrivileges() {
|
||||||
|
return privileges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivileges(final Collection<Privilege> privileges) {
|
||||||
|
this.privileges = privileges;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Role role = (Role) obj;
|
||||||
|
if (!role.equals(role.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Role [name=").append(name).append("]").append("[id=").append(id).append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
package org.baeldung.rolesauthorities.model;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinTable;
|
||||||
|
import javax.persistence.ManyToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "user_account")
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@Column(length = 60)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
private boolean isUsing2FA;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.EAGER)
|
||||||
|
@JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
|
||||||
|
private Collection<Role> roles;
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
super();
|
||||||
|
this.enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(final String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(final String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(final String username) {
|
||||||
|
this.email = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(final String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Role> getRoles() {
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoles(final Collection<Role> roles) {
|
||||||
|
this.roles = roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(final boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUsing2FA() {
|
||||||
|
return isUsing2FA;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsing2FA(boolean isUsing2FA) {
|
||||||
|
this.isUsing2FA = isUsing2FA;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = (prime * result) + ((email == null) ? 0 : email.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final User user = (User) obj;
|
||||||
|
if (!email.equals(user.email)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("User [id=").append(id).append(", firstName=")
|
||||||
|
.append(firstName).append(", lastName=").append(lastName).append(", email=").append(email).append(", password=").append(password).append(", enabled=").append(enabled).append(", roles=").append(roles).append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package org.baeldung.rolesauthorities.persistence;
|
||||||
|
|
||||||
|
import org.baeldung.rolesauthorities.model.User;
|
||||||
|
|
||||||
|
public interface IUserService {
|
||||||
|
|
||||||
|
User findUserByEmail(String email);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package org.baeldung.rolesauthorities.persistence;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||||
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableTransactionManagement
|
||||||
|
@PropertySource({ "classpath:persistence.properties" })
|
||||||
|
@ComponentScan({ "org.baeldung.rolesauthorities.persistence" })
|
||||||
|
@EnableJpaRepositories(basePackages = "org.baeldung.rolesauthorities.persistence")
|
||||||
|
public class PersistenceJPAConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment env;
|
||||||
|
|
||||||
|
public PersistenceJPAConfig() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||||
|
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
|
||||||
|
em.setDataSource(dataSource());
|
||||||
|
em.setPackagesToScan(new String[] { "org.baeldung.rolesauthorities" });
|
||||||
|
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||||
|
em.setJpaVendorAdapter(vendorAdapter);
|
||||||
|
em.setJpaProperties(additionalProperties());
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DataSource dataSource() {
|
||||||
|
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||||
|
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
|
||||||
|
dataSource.setUrl(env.getProperty("jdbc.url"));
|
||||||
|
dataSource.setUsername(env.getProperty("jdbc.user"));
|
||||||
|
dataSource.setPassword(env.getProperty("jdbc.pass"));
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JpaTransactionManager transactionManager() {
|
||||||
|
final JpaTransactionManager transactionManager = new JpaTransactionManager();
|
||||||
|
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
|
||||||
|
return transactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
|
||||||
|
return new PersistenceExceptionTranslationPostProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Properties additionalProperties() {
|
||||||
|
final Properties hibernateProperties = new Properties();
|
||||||
|
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
|
||||||
|
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
|
||||||
|
return hibernateProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package org.baeldung.rolesauthorities.persistence;
|
||||||
|
|
||||||
|
import org.baeldung.rolesauthorities.model.Privilege;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface PrivilegeRepository extends JpaRepository<Privilege, Long> {
|
||||||
|
|
||||||
|
Privilege findByName(String name);
|
||||||
|
|
||||||
|
void delete(Privilege privilege);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package org.baeldung.rolesauthorities.persistence;
|
||||||
|
|
||||||
|
import org.baeldung.rolesauthorities.model.Role;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface RoleRepository extends JpaRepository<Role, Long> {
|
||||||
|
|
||||||
|
Role findByName(String name);
|
||||||
|
|
||||||
|
void delete(Role role);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package org.baeldung.rolesauthorities.persistence;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.baeldung.rolesauthorities.model.Privilege;
|
||||||
|
import org.baeldung.rolesauthorities.model.Role;
|
||||||
|
import org.baeldung.rolesauthorities.model.User;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SetupDataLoader implements ApplicationListener<ContextRefreshedEvent> {
|
||||||
|
|
||||||
|
private boolean alreadySetup = false;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RoleRepository roleRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PrivilegeRepository privilegeRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void onApplicationEvent(final ContextRefreshedEvent event) {
|
||||||
|
if (alreadySetup) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// == create initial privileges
|
||||||
|
final Privilege readPrivilege = createPrivilegeIfNotFound("READ_PRIVILEGE");
|
||||||
|
final Privilege writePrivilege = createPrivilegeIfNotFound("WRITE_PRIVILEGE");
|
||||||
|
|
||||||
|
// == create initial roles
|
||||||
|
final List<Privilege> adminPrivileges = Arrays.asList(readPrivilege, writePrivilege);
|
||||||
|
createRoleIfNotFound("ROLE_ADMIN", adminPrivileges);
|
||||||
|
List<Privilege> rolePrivileges = new ArrayList<>();
|
||||||
|
createRoleIfNotFound("ROLE_USER", rolePrivileges);
|
||||||
|
|
||||||
|
final Role adminRole = roleRepository.findByName("ROLE_ADMIN");
|
||||||
|
final User user = new User();
|
||||||
|
user.setFirstName("Admin");
|
||||||
|
user.setLastName("Admin");
|
||||||
|
user.setEmail("admin@test.com");
|
||||||
|
user.setPassword(passwordEncoder.encode("admin"));
|
||||||
|
user.setRoles(Arrays.asList(adminRole));
|
||||||
|
user.setEnabled(true);
|
||||||
|
userRepository.save(user);
|
||||||
|
|
||||||
|
final Role basicRole = roleRepository.findByName("ROLE_USER");
|
||||||
|
final User basicUser = new User();
|
||||||
|
basicUser.setFirstName("User");
|
||||||
|
basicUser.setLastName("User");
|
||||||
|
basicUser.setEmail("user@test.com");
|
||||||
|
basicUser.setPassword(passwordEncoder.encode("user"));
|
||||||
|
basicUser.setRoles(Arrays.asList(basicRole));
|
||||||
|
basicUser.setEnabled(true);
|
||||||
|
userRepository.save(basicUser);
|
||||||
|
|
||||||
|
alreadySetup = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
private final Privilege createPrivilegeIfNotFound(final String name) {
|
||||||
|
Privilege privilege = privilegeRepository.findByName(name);
|
||||||
|
if (privilege == null) {
|
||||||
|
privilege = new Privilege(name);
|
||||||
|
privilegeRepository.save(privilege);
|
||||||
|
}
|
||||||
|
return privilege;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
private final Role createRoleIfNotFound(final String name, final Collection<Privilege> privileges) {
|
||||||
|
Role role = roleRepository.findByName(name);
|
||||||
|
if (role == null) {
|
||||||
|
role = new Role(name);
|
||||||
|
role.setPrivileges(privileges);
|
||||||
|
roleRepository.save(role);
|
||||||
|
}
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package org.baeldung.rolesauthorities.persistence;
|
||||||
|
|
||||||
|
import org.baeldung.rolesauthorities.model.User;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
|
|
||||||
|
User findByEmail(String email);
|
||||||
|
|
||||||
|
void delete(User user);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package org.baeldung.rolesauthorities.persistence;
|
||||||
|
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
import org.baeldung.rolesauthorities.model.User;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional
|
||||||
|
public class UserService implements IUserService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository repository;
|
||||||
|
|
||||||
|
public User findUserByEmail(final String email) {
|
||||||
|
return repository.findByEmail(email);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
server.port=8082
|
||||||
|
server.context-path=/
|
||||||
|
spring.datasource.driver-class-name=org.h2.Driver
|
||||||
|
spring.datasource.url=jdbc:h2:mem:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||||
|
spring.datasource.username=sa
|
||||||
|
spring.datasource.password=
|
||||||
|
spring.jpa.hibernate.ddl-auto=create-drop
|
||||||
|
spring.jpa.database=H2
|
||||||
|
spring.jpa.show-sql=false
|
||||||
|
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
|
@ -0,0 +1,11 @@
|
|||||||
|
####### H2
|
||||||
|
#################### DataSource Configuration ##########################
|
||||||
|
jdbc.driverClassName=org.h2.Driver
|
||||||
|
jdbc.url=jdbc:h2:mem:registration_02;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||||
|
jdbc.user=sa
|
||||||
|
jdbc.pass=
|
||||||
|
init-db=false
|
||||||
|
#################### Hibernate Configuration ##########################
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||||
|
hibernate.show_sql=false
|
||||||
|
hibernate.hbm2ddl.auto=create-drop
|
@ -0,0 +1,25 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"/>
|
||||||
|
<title>Role vs Granted Authority Example</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-default">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<a class="navbar-brand" href="#">Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container">
|
||||||
|
<br/>
|
||||||
|
<a href="/protectedbynothing">Unprotected Resource</a><br/>
|
||||||
|
<a href="/protectedbyrole">Resource Protected By Role</a><br/>
|
||||||
|
<a href="/protectedbyauthority">Resource Protected By Authority</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -0,0 +1,57 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
|
||||||
|
<title>Login</title>
|
||||||
|
<script th:inline="javascript">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
function validate() {
|
||||||
|
if (document.f.username.value == "" && document.f.password.value == "") {
|
||||||
|
alert(/*[[#{message.username} + #{message.password}]]*/);
|
||||||
|
document.f.username.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (document.f.username.value == "") {
|
||||||
|
alert(/*[[#{message.username}]]*/);
|
||||||
|
document.f.username.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (document.f.password.value == "") {
|
||||||
|
alert(/*[[#{message.password}]]*/);
|
||||||
|
document.f.password.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*]]>*/
|
||||||
|
</script>
|
||||||
|
<style type="text/css">
|
||||||
|
.wrapper{width:500px;margin-left:auto;margin-right:auto}
|
||||||
|
label{padding-left:0 !important}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row wrapper">
|
||||||
|
<h1>Login</h1>
|
||||||
|
<br/><br/>
|
||||||
|
|
||||||
|
<form name='f' action="login" method='POST' onsubmit="return validate();">
|
||||||
|
|
||||||
|
<label class="col-sm-4">Email</label>
|
||||||
|
<span class="col-sm-8"><input class="form-control" type='text' name='username' value=''/></span>
|
||||||
|
|
||||||
|
<br/><br/>
|
||||||
|
<label class="col-sm-4">Password</label>
|
||||||
|
<span class="col-sm-8"><input class="form-control" type='password' name='password' /></span>
|
||||||
|
|
||||||
|
<br/><br/>
|
||||||
|
<input class="btn btn-primary" name="submit" type="submit" />
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -0,0 +1,24 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
|
||||||
|
<title>Protected By Authority</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-default">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<a class="navbar-brand" href="#">Protected By Authority</a>
|
||||||
|
</div>
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<li><a href="/logout">Logout</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Protected By Authority</h1>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,21 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
|
||||||
|
<title>Protected By Nothing</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-default">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<a class="navbar-brand" href="#">Protected By Nothing</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Protected By Nothing</h1>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
|
||||||
|
<title>Protected By Role</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-default">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<a class="navbar-brand" href="#">Protected By Role</a>
|
||||||
|
</div>
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<li><a href="/logout">Logout</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Protected By Role</h1>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user