Merge pull request #136 from Doha2012/master
prevent brute force authentications
This commit is contained in:
commit
1d026ac087
|
@ -2,6 +2,7 @@ package org.baeldung.persistence.model;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
|
@ -23,6 +24,7 @@ public class User {
|
|||
|
||||
private String email;
|
||||
|
||||
@Column(length = 60)
|
||||
private String password;
|
||||
|
||||
private boolean enabled;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package org.baeldung.security;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetails;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AuthenticationFailureListener implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {
|
||||
|
||||
@Autowired
|
||||
private LoginAttemptService loginAttemptService;
|
||||
|
||||
public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent e) {
|
||||
WebAuthenticationDetails auth = (WebAuthenticationDetails) e.getAuthentication().getDetails();
|
||||
loginAttemptService.loginFailed(auth.getRemoteAddress());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.baeldung.security;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetails;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AuthenticationSuccessEventListener implements ApplicationListener<AuthenticationSuccessEvent> {
|
||||
|
||||
@Autowired
|
||||
private LoginAttemptService loginAttemptService;
|
||||
|
||||
public void onApplicationEvent(AuthenticationSuccessEvent e) {
|
||||
WebAuthenticationDetails auth = (WebAuthenticationDetails) e.getAuthentication().getDetails();
|
||||
loginAttemptService.loginSucceeded(auth.getRemoteAddress());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package org.baeldung.security;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
@Service
|
||||
public class LoginAttemptService {
|
||||
|
||||
private final int MAX_ATTEMPT = 10;
|
||||
private LoadingCache<String, Integer> attemptsCache;
|
||||
|
||||
public LoginAttemptService() {
|
||||
super();
|
||||
attemptsCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.DAYS).build(new CacheLoader<String, Integer>() {
|
||||
public Integer load(String key) {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loginSucceeded(String key) {
|
||||
attemptsCache.invalidate(key);
|
||||
}
|
||||
|
||||
public void loginFailed(String key) {
|
||||
int attempts = 0;
|
||||
try {
|
||||
attempts = attemptsCache.get(key);
|
||||
} catch (ExecutionException e) {
|
||||
attempts = 0;
|
||||
}
|
||||
attempts++;
|
||||
attemptsCache.put(key, attempts);
|
||||
}
|
||||
|
||||
public boolean isBlocked(String key) {
|
||||
try {
|
||||
return attemptsCache.get(key) >= MAX_ATTEMPT;
|
||||
} catch (ExecutionException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import java.util.Arrays;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.baeldung.persistence.dao.RoleRepository;
|
||||
import org.baeldung.persistence.dao.UserRepository;
|
||||
import org.baeldung.persistence.model.Privilege;
|
||||
|
@ -34,6 +36,12 @@ public class MyUserDetailsService implements UserDetailsService {
|
|||
@Autowired
|
||||
private RoleRepository roleRepository;
|
||||
|
||||
@Autowired
|
||||
private LoginAttemptService loginAttemptService;
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
public MyUserDetailsService() {
|
||||
super();
|
||||
}
|
||||
|
@ -42,6 +50,11 @@ public class MyUserDetailsService implements UserDetailsService {
|
|||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(final String email) throws UsernameNotFoundException {
|
||||
String ip = request.getRemoteAddr();
|
||||
if (loginAttemptService.isBlocked(ip)) {
|
||||
throw new RuntimeException("blocked");
|
||||
}
|
||||
|
||||
try {
|
||||
final User user = userRepository.findByEmail(email);
|
||||
if (user == null) {
|
||||
|
|
|
@ -58,4 +58,5 @@ message.resendToken=We will send you a message with a new registration token to
|
|||
message.forgetPassword=Forget Password
|
||||
message.resetPassword=Reset Password
|
||||
message.updatePassword=Update Password
|
||||
message.userNotFound=User Not Found
|
||||
message.userNotFound=User Not Found
|
||||
auth.message.blocked=This ip is blocked for 24 hours
|
|
@ -58,4 +58,5 @@ message.resendToken=Le enviaremos un mensaje con un nuevo token de registro en s
|
|||
message.forgetPassword=Olvide la contraseña
|
||||
message.resetPassword=Restablecer contraseña
|
||||
message.updatePassword=Actualizar contraseña
|
||||
message.userNotFound=Usuario no encontrado
|
||||
message.userNotFound=Usuario no encontrado
|
||||
auth.message.blocked=Esta IP se bloquea durante 24 horas
|
|
@ -21,6 +21,12 @@
|
|||
<spring:message code="auth.message.expired"></spring:message>
|
||||
</div>
|
||||
</c:when>
|
||||
<c:when
|
||||
test="${SPRING_SECURITY_LAST_EXCEPTION.message == 'blocked'}">
|
||||
<div class="alert alert-error">
|
||||
<spring:message code="auth.message.blocked"></spring:message>
|
||||
</div>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<div class="alert alert-error">
|
||||
<!-- <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/> -->
|
||||
|
|
|
@ -16,7 +16,11 @@
|
|||
<listener>
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
|
||||
|
||||
<listener>
|
||||
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>mvc</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
package org.baeldung.config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
import org.springframework.security.authentication.InsufficientAuthenticationException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException;
|
||||
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
|
||||
import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException;
|
||||
import org.springframework.security.oauth2.client.token.AccessTokenProvider;
|
||||
import org.springframework.security.oauth2.client.token.AccessTokenRequest;
|
||||
import org.springframework.security.oauth2.client.token.ClientTokenServices;
|
||||
import org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
|
||||
public class MyAccessTokenProviderChain extends OAuth2AccessTokenSupport implements AccessTokenProvider {
|
||||
|
||||
private final List<AccessTokenProvider> chain;
|
||||
|
||||
private ClientTokenServices clientTokenServices;
|
||||
|
||||
public MyAccessTokenProviderChain(List<? extends AccessTokenProvider> chain) {
|
||||
this.chain = chain == null ? Collections.<AccessTokenProvider> emptyList() : Collections.unmodifiableList(chain);
|
||||
}
|
||||
|
||||
public void setClientTokenServices(ClientTokenServices clientTokenServices) {
|
||||
this.clientTokenServices = clientTokenServices;
|
||||
}
|
||||
|
||||
public boolean supportsResource(OAuth2ProtectedResourceDetails resource) {
|
||||
for (AccessTokenProvider tokenProvider : chain) {
|
||||
if (tokenProvider.supportsResource(resource)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource) {
|
||||
for (AccessTokenProvider tokenProvider : chain) {
|
||||
if (tokenProvider.supportsRefresh(resource)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public OAuth2AccessToken obtainAccessToken(OAuth2ProtectedResourceDetails resource, AccessTokenRequest request) throws UserRedirectRequiredException, AccessDeniedException {
|
||||
System.out.println("Obtain new token=====");
|
||||
OAuth2AccessToken accessToken = null;
|
||||
OAuth2AccessToken existingToken = null;
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
System.out.println("The authentication is ---- " + auth);
|
||||
if (auth instanceof AnonymousAuthenticationToken) {
|
||||
if (!resource.isClientOnly()) {
|
||||
throw new InsufficientAuthenticationException("Authentication is required to obtain an access token (anonymous not allowed)");
|
||||
}
|
||||
}
|
||||
|
||||
if (resource.isClientOnly() || (auth != null && auth.isAuthenticated())) {
|
||||
existingToken = request.getExistingToken();
|
||||
System.out.println("checking existing token =====");
|
||||
if (existingToken == null && clientTokenServices != null) {
|
||||
System.out.println("get existing token from clientTokenServices ==== ");
|
||||
existingToken = clientTokenServices.getAccessToken(resource, auth);
|
||||
}
|
||||
|
||||
if (existingToken != null) {
|
||||
if (existingToken.isExpired()) {
|
||||
System.out.println("expired token");
|
||||
if (clientTokenServices != null) {
|
||||
clientTokenServices.removeAccessToken(resource, auth);
|
||||
}
|
||||
OAuth2RefreshToken refreshToken = existingToken.getRefreshToken();
|
||||
if (refreshToken != null) {
|
||||
System.out.println("let's refresh it");
|
||||
accessToken = refreshAccessToken(resource, refreshToken, request);
|
||||
}
|
||||
} else {
|
||||
System.out.println("use existing because not expired yet");
|
||||
accessToken = existingToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (accessToken == null) {
|
||||
System.out.println("no token so let get it");
|
||||
accessToken = obtainNewAccessTokenInternal(resource, request);
|
||||
|
||||
if (accessToken == null) {
|
||||
throw new IllegalStateException("An OAuth 2 access token must be obtained or an exception thrown.");
|
||||
}
|
||||
}
|
||||
|
||||
if (clientTokenServices != null && auth != null && auth.isAuthenticated()) {
|
||||
clientTokenServices.saveAccessToken(resource, auth, accessToken);
|
||||
}
|
||||
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
protected OAuth2AccessToken obtainNewAccessTokenInternal(OAuth2ProtectedResourceDetails details, AccessTokenRequest request) throws UserRedirectRequiredException, AccessDeniedException {
|
||||
|
||||
if (request.isError()) {
|
||||
throw OAuth2Exception.valueOf(request.toSingleValueMap());
|
||||
}
|
||||
|
||||
for (AccessTokenProvider tokenProvider : chain) {
|
||||
if (tokenProvider.supportsResource(details)) {
|
||||
System.out.println("we will use this provider to get it => " + tokenProvider.getClass().getName());
|
||||
return tokenProvider.obtainAccessToken(details, request);
|
||||
}
|
||||
}
|
||||
|
||||
throw new OAuth2AccessDeniedException("Unable to obtain a new access token for resource '" + details.getId() + "'. The provider manager is not configured to support it.", details);
|
||||
}
|
||||
|
||||
public OAuth2AccessToken refreshAccessToken(OAuth2ProtectedResourceDetails resource, OAuth2RefreshToken refreshToken, AccessTokenRequest request) throws UserRedirectRequiredException {
|
||||
for (AccessTokenProvider tokenProvider : chain) {
|
||||
if (tokenProvider.supportsRefresh(resource)) {
|
||||
System.out.println("we will use this provider to refresh it => " + tokenProvider.getClass().getName());
|
||||
return tokenProvider.refreshAccessToken(resource, refreshToken, request);
|
||||
}
|
||||
}
|
||||
throw new OAuth2AccessDeniedException("Unable to obtain a new access token for resource '" + resource.getId() + "'. The provider manager is not configured to support it.", resource);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
package org.baeldung.config;
|
||||
|
||||
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.persistence" })
|
||||
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao")
|
||||
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.persistence.model" });
|
||||
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();
|
||||
}
|
||||
|
||||
final 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
package org.baeldung.config;
|
||||
|
||||
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;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@ComponentScan(basePackages = { "org.baeldung.security" })
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
@Bean
|
||||
public DaoAuthenticationProvider authProvider() {
|
||||
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||
authProvider.setUserDetailsService(userDetailsService);
|
||||
return authProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.authenticationProvider(authProvider());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(WebSecurity web) throws Exception {
|
||||
web.ignoring().antMatchers("/resources/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http.anonymous().disable().authorizeRequests()
|
||||
.antMatchers("/**").permitAll()
|
||||
.antMatchers("/reddit","/reddit/**").hasRole("User");
|
||||
// .and()
|
||||
// .formLogin()
|
||||
// .loginPage("/login")
|
||||
// .permitAll();
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
|
@ -13,7 +13,7 @@ public class ServletInitializer extends AbstractDispatcherServletInitializer {
|
|||
@Override
|
||||
protected WebApplicationContext createServletApplicationContext() {
|
||||
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||
context.register(PersistenceJPAConfig.class, SecurityConfig.class, WebConfig.class);
|
||||
context.register(WebConfig.class);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,6 @@ public class ServletInitializer extends AbstractDispatcherServletInitializer {
|
|||
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||
super.onStartup(servletContext);
|
||||
registerProxyFilter(servletContext, "oauth2ClientContextFilter");
|
||||
// registerProxyFilter(servletContext, "springSecurityFilterChain");
|
||||
}
|
||||
|
||||
private void registerProxyFilter(ServletContext servletContext, String name) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.springframework.security.oauth2.client.OAuth2ClientContext;
|
|||
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
|
||||
import org.springframework.security.oauth2.client.token.AccessTokenProvider;
|
||||
import org.springframework.security.oauth2.client.token.AccessTokenProviderChain;
|
||||
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider;
|
||||
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
|
||||
import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitAccessTokenProvider;
|
||||
|
@ -92,7 +93,7 @@ public class WebConfig extends WebMvcConfigurerAdapter {
|
|||
@Bean
|
||||
public OAuth2RestTemplate redditRestTemplate(OAuth2ClientContext clientContext) {
|
||||
OAuth2RestTemplate template = new OAuth2RestTemplate(reddit(), clientContext);
|
||||
AccessTokenProvider accessTokenProvider = new MyAccessTokenProviderChain(Arrays.<AccessTokenProvider> asList(new MyAuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(), new ResourceOwnerPasswordAccessTokenProvider(),
|
||||
AccessTokenProvider accessTokenProvider = new AccessTokenProviderChain(Arrays.<AccessTokenProvider> asList(new MyAuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(), new ResourceOwnerPasswordAccessTokenProvider(),
|
||||
new ClientCredentialsAccessTokenProvider()));
|
||||
template.setAccessTokenProvider(accessTokenProvider);
|
||||
return template;
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package org.baeldung.persistence.dao;
|
||||
|
||||
import org.baeldung.persistence.model.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
public User findByUsername(String name);
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package org.baeldung.persistence.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class User {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
public User() {
|
||||
super();
|
||||
}
|
||||
|
||||
public User(String username, String password) {
|
||||
super();
|
||||
this.username = username;
|
||||
this.password = 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package org.baeldung.security;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.baeldung.persistence.dao.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.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(final String name) {
|
||||
org.baeldung.persistence.model.User user = userRepository.findByUsername(name);
|
||||
if (user == null) {
|
||||
user = new org.baeldung.persistence.model.User(name, UUID.randomUUID().toString());
|
||||
user = userRepository.save(user);
|
||||
}
|
||||
return new User(user.getUsername(), user.getPassword(), getGrantedAuthorities(Arrays.asList("ROLE_USER")));
|
||||
}
|
||||
|
||||
private static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
|
||||
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
|
||||
for (String role : roles) {
|
||||
authorities.add(new SimpleGrantedAuthority(role));
|
||||
}
|
||||
return authorities;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,5 @@
|
|||
package org.baeldung.web;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
|
@ -17,9 +11,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
@Controller
|
||||
public class RedditController {
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
private OAuth2RestTemplate redditRestTemplate;
|
||||
|
||||
@RequestMapping("/info")
|
||||
|
@ -28,18 +19,9 @@ public class RedditController {
|
|||
JsonNode node = new ObjectMapper().readTree(result);
|
||||
String name = node.get("name").asText();
|
||||
model.addAttribute("info", name);
|
||||
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(name);
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
return "reddit";
|
||||
}
|
||||
|
||||
@RequestMapping("/reddit/test")
|
||||
public String test(Model model) {
|
||||
return "test";
|
||||
}
|
||||
|
||||
public void setRedditRestTemplate(OAuth2RestTemplate redditRestTemplate) {
|
||||
this.redditRestTemplate = redditRestTemplate;
|
||||
}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
################### DataSource Configuration ##########################
|
||||
jdbc.driverClassName=com.mysql.jdbc.Driver
|
||||
jdbc.url=jdbc:mysql://localhost:3306/oauth?createDatabaseIfNotExist=true
|
||||
jdbc.user=tutorialuser
|
||||
jdbc.pass=tutorialmy5ql
|
||||
init-db=false
|
||||
################### Hibernate Configuration ##########################
|
||||
hibernate.dialect=org.hibernate.dialect.MySQLDialect
|
||||
hibernate.show_sql=false
|
||||
hibernate.hbm2ddl.auto=create-drop
|
|
@ -7,6 +7,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<h1>Test</h1>
|
||||
<b>Test </b>
|
||||
<b>Test </b>${info}
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue