LDAP + Spring: how to correctly authenticate? - java

I realize LDAP authentication by Spring. In my case, I use ActiveDirectoryLdapAuthenticationProvider.
It looks like here:
private Authentication authenticate(String username, String password, HelpDescUser userDetails) {
String url = "ldap://" + ldapHost + ":" + port + "/";
ActiveDirectoryLdapAuthenticationProvider ldapProvider =
new ActiveDirectoryLdapAuthenticationProvider(domain, url, rootDn);
String filterWithName = String.format(filter, username);
ldapProvider.setSearchFilter(filterWithName);
ldapProvider.setContextEnvironmentProperties(createProperties(username, password));
ldapProvider.setConvertSubErrorCodesToExceptions(true);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password);
Authentication authenticate;
try {
authenticate = ldapProvider.authenticate(authentication);
} catch (Exception e) {
throw new BadCredentialsException("Пользователь не авторизован (сервер LDAP не подтвердил авторизацию).");
}
if (Objects.nonNull(authenticate) && authenticate.isAuthenticated()) {
return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
} else {
throw new BadCredentialsException("Пользователь не авторизован (сервер LDAP не подтвердил авторизацию).");
}
}
private Map<String, Object> createProperties(String username, String password) {
Map<String, Object> properties = new HashMap<>();
properties.put(Context.SECURITY_PRINCIPAL, username);
properties.put(Context.SECURITY_CREDENTIALS, password);
return properties;
}
I have a problem.
As I understand authentication schema, when we authenticate by user, we also need to have a technical account. We bind by technical account & than sending user login & password, & after that, we receive answer. But in this schema, we bind with the same user to authenticate, & it's wrong - this user may have no rights to bind.
Please, show me working solution to authenticate with Spring ActiveDirectoryLdapAuthenticationProvider?

When you declare ActiveDirectoryLdapAuthenticationProvider bean, you can use setContextEnvironmentProperties() method.
In example:
#Bean
public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(null, ldapUrls, ldapBase);
setContextEnvironmentProperties(provider);
return provider;
}
private void setContextEnvironmentProperties(ActiveDirectoryLdapAuthenticationProvider provider) {
Map<String, Object> contextEnvironmentProperties = new HashMap<>();
if (StringUtils.isNotEmpty(ldapUsername)) {
contextEnvironmentProperties.put(Context.SECURITY_PRINCIPAL, ldapUsername);
}
if (StringUtils.isNotEmpty(ldapPassword)) {
contextEnvironmentProperties.put(Context.SECURITY_CREDENTIALS, ldapPassword);
}
if (!contextEnvironmentProperties.isEmpty()) {
provider.setContextEnvironmentProperties(contextEnvironmentProperties);
}
}

Related

Spring Security 5.x, WebFlux, Reactive, How to store Authentication in ReactiveSecurityContextHolder

I am building a OAuth2 authorization server using Spring Boot 2.3.1 and WebFlux. I am running into a issue. After successfully authenticating, the Authorization object is missing from the ReactiveSecurityContextHolder object.
I have an implementation of ServerSecurityContextRepository which implements the load method as below.
#Override
public Mono load(ServerWebExchange swe) {
return swe.getSession().map(WebSession::getAttributes).flatMap((attrs) -> {
ServerHttpRequest request = swe.getRequest();
String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
if (authHeader != null && authHeader.startsWith("Bearer ") && authHeader.contains(" ")) {
// Split the auth header at space and the second token is the authToken.
String authToken = authHeader.split(" ")[1];
try {
// Some code removed here.
Authentication auth = new UsernamePasswordAuthenticationToken(principal, authToken);
SecurityContext sc = (SecurityContext)attrs.get(VarahamihirConstants.SECURITY_CONTEXT_ATTRIBUTE);
if (sc == null) {
sc = new SecurityContextImpl(auth);
save(swe, sc);
}
final SecurityContext context = sc;
return this.authenticationManager.authenticate(auth).map((authentication) -> {
context.setAuthentication(authentication);
return context;
});
} catch (ParseException|JOSEException|BadJOSEException e) {
return Mono.error(new UnauthorizedException("The auth token is invalid."));
}
} else {
return Mono.empty();
}
});
}
I also have an implementation of ReactiveAuthenticationManager which implements authenticate method.
public Mono<Authentication> authenticate(Authentication authentication) {
String authToken = authentication.getCredentials().toString();
try {
Principal principal = authentication.getPrincipal();
if (!jwtUtil.validateToken(principal.getAuthToken())) {
return Mono.empty();
}
// Some code removed.
Authentication auth = new UsernamePasswordAuthenticationToken(principal,
authToken,
actualAuthorities);
return Mono.just(auth);
})
return Mono.just(auth);
}
//SecurityContextHolder.getContext().setAuthentication(auth);
} catch (Exception e) {
e.printStackTrace();
return Mono.error(e);
}
return Mono.error(new UnauthorizedException("Unreachable place."));
}
After this, the code works fine in handling the authentication flow but the ReactiveSecurityContextHolder does not contain any context. Also because of that any of the PrePost annotations can't be used.
I intuitively understand, somewhere I have to save the context into context holder but where?

How to use email as a username in Spring Security?

I have to remove a login field from my User class and use email as a username in SecurityUtils
I've already changed j_username parameter in a frontend, but now the issue remains on a backend
public static String getCurrentUserLogin() {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
String userName = null;
if (authentication != null) {
if (authentication.getPrincipal() instanceof UserDetails) {
UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
userName = springSecurityUser.getUsername();
} else if (authentication.getPrincipal() instanceof String) {
userName = (String) authentication.getPrincipal();
}
}
return userName;
}
and as a result userName is null, becauseUserDetails and Authentication don't have email. How could I set the field email as a 'j_username'? I've tried this
How to login by email instead of username in spring security
solution but it's not enough since I use an anonymousUser
Also, I have an implementation of UserDetailsService but when debugging it's not called when being the anonymousUser
public class DomainUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
public DomainUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
#Override
public UserDetails loadUserByUsername(final String login) {
String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
Optional<User> userFromDatabase = userRepository.findOneByLogin(lowercaseLogin);
return userFromDatabase.map(user -> {
if (!user.getActivated()) {
throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated");
}
List<GrantedAuthority> grantedAuthorities = user.getAuthorities().stream()
.map(authority -> new SimpleGrantedAuthority(authority.getName()))
.collect(Collectors.toList());
return new org.springframework.security.core.userdetails.User(lowercaseLogin,
user.getPassword(),
grantedAuthorities);
}).orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the " +
"database"));
}
}
In order to achieve your goal you will have to control anonymous user behavior. I had that issue before and when the user is logged in the queries are working fine. As M. Denim suggested you should search by email here -> Optional<User> userFromDatabase = userRepository.findOneByEmail(lowercaseLogin);
But in case of anonymous user in getCurrentUserLogin() you have to write an if statement to return anonymous#localhost in case the userName = anonymousUser
here i share some code from my Spring Security Configuration class
.formLogin().loginPage("/login")
.usernameParameter("logInId").passwordParameter("password")
here i use 'logInId' parameter for login instead of default parameter....
i think you searching some thing like this .......

Errai security with PicketLink

I have this CustomAuthenticator for user with Errai Security:
public CustomAuthenticator extends BaseAuthenticator {
#Override
public void authenticate() {
String userId = loginCredentials.getUserId();
String password = loginCredentials.getPassword();
User user = userDAO.fetchUserByName(userId);
if (!BCrypt.checkpw(password, user.getPasswordHash())) {
setStatus(AuthenticationStatus.FAILURE);
} else {
// Add to IDM
IdentityQuery<UserImpl> query
= partitionManager.createIdentityManager().createIdentityQuery(UserImpl.class);
query.setParameter(UserImpl.LOGIN_NAME, user.getUsername());
List<UserImpl> result = query.getResultList();
org.picketlink.idm.model.basic.Role trial = new org.picketlink.idm.model.basic.Role("TRIAL");
if (result.isEmpty()){
UserImpl account = new UserImpl(user);
partitionManager.createIdentityManager().add(account);
partitionManager.createIdentityManager().updateCredential(account, new Password(password));
partitionManager.createIdentityManager().add(trial);
BasicModel.grantRole(partitionManager.createRelationshipManager(), account, trial);
IdentityQuery<UserImpl> q
= partitionManager.createIdentityManager().createIdentityQuery(UserImpl.class);
q.setParameter(UserImpl.LOGIN_NAME, user.getUsername());
UserImpl u = q.getResultList().iterator().next();
setStatus(AuthenticationStatus.SUCCESS);
setAccount(u);
} else {
setStatus(AuthenticationStatus.SUCCESS);
setAccount(result.iterator().next());
}
userEvent.fire(user);
}
}
Even I check the seAccount Account to be set is ok, I am not sure if the Roles is persisted at list at the Picketlink side; because the response of the call:
Caller<AuthenticationService> authServiceCaller;
The Errai Security User returned although not null, the names is "ANONYMOUS" and role is "NOBODY" I'm not sure what's happening here.
Update:
The login(username, password) method returns the correct User and Role, but getUser() does not. This is the issue.

Spring OAuth2 - Manually creating an access token in the token store

I have a situation where I would like to create an access token myself (so not through the usual process). I have come up with something like this:
#Inject
private DefaultTokenServices defaultTokenServices;
...
OAuth2Authentication auth = xxx;
OAuth2AccessToken token = defaultTokenServices.createAccessToken(auth);
The only problem is that I am not sure how to create the OAuth2Authentication (in my code the part with xxx). I have the user & client info and I know which Authorities I want to grant this token.
Here it is, your use case may differ slightly based on the flow you are using. This is what works for a password grant flow. There are a few custom class like token store, token enhancer ect. but that is really just extended versions of the spring classes modified for our own needs.
HashMap<String, String> authorizationParameters = new HashMap<String, String>();
authorizationParameters.put("scope", "read");
authorizationParameters.put("username", "mobile_client");
authorizationParameters.put("client_id", "mobile-client");
authorizationParameters.put("grant", "password");
DefaultAuthorizationRequest authorizationRequest = new DefaultAuthorizationRequest(authorizationParameters);
authorizationRequest.setApproved(true);
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_UNTRUSTED_CLIENT"));
authorizationRequest.setAuthorities(authorities);
HashSet<String> resourceIds = new HashSet<String>();
resourceIds.add("mobile-public");
authorizationRequest.setResourceIds(resourceIds);
// Create principal and auth token
User userPrincipal = new User(user.getUserID(), "", true, true, true, true, authorities);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userPrincipal, null, authorities) ;
OAuth2Authentication authenticationRequest = new OAuth2Authentication(authorizationRequest, authenticationToken);
authenticationRequest.setAuthenticated(true);
CustomTokenStore tokenStore = new CustomTokenStore();
// Token Enhancer
CustomTokenEnhancer tokenEnhancer = new CustomTokenEnhancer(user.getUserID());
CustomTokenServices tokenServices = new CustomTokenServices();
tokenServices.setTokenEnhancer(tokenEnhancer);
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(tokenStore);
OAuth2AccessToken accessToken = tokenServices.createAccessTokenForUser(authenticationRequest, user);
Here is how to generate a Token using the TokenEndpoint interface (used to expose REST service) :
#Inject
private TokenEndpoint tokenEndpoint;
public ResponseEntity<?> getToken(Principal principal) {
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("client_id", "appid");
parameters.put("client_secret", "myOAuthSecret");
parameters.put("grant_type", "password");
parameters.put("password", myUser.getPassword());
parameters.put("scope", "read write");
parameters.put("username", myUser.getLogin());
return tokenEndpoint.getAccessToken(principal, parameters);
}
Other way, to manually generate an OAuth2 Accesss Token we can use an instance of TokenService
#Autowired
private AuthorizationServerEndpointsConfiguration configuration;
#Override
public String generateOAuth2AccessToken(User user, List<Role> roles, List<String> scopes) {
Map<String, String> requestParameters = new HashMap<String, String>();
Map<String, Serializable> extensionProperties = new HashMap<String, Serializable>();
boolean approved = true;
Set<String> responseTypes = new HashSet<String>();
responseTypes.add("code");
// Authorities
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for(Role role: roles)
authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName()));
OAuth2Request oauth2Request = new OAuth2Request(requestParameters, "clientIdTest", authorities, approved, new HashSet<String>(scopes), new HashSet<String>(Arrays.asList("resourceIdTest")), null, responseTypes, extensionProperties);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), "N/A", authorities);
OAuth2Authentication auth = new OAuth2Authentication(oauth2Request, authenticationToken);
AuthorizationServerTokenServices tokenService = configuration.getEndpointsConfigurer().getTokenServices();
OAuth2AccessToken token = tokenService.createAccessToken(auth);
return token.getValue();
}
I based my solution on Mop So's answer but instead of using:
return tokenEndpoint.getAccessToken(principal, parameters);
I used:
tokenEndpoint.postAccessToken(principal, parameters);
Why? Because if you use tokenEndpoint.getAccessToken(principal, parameters) the endpoing will throw you a HttpRequestMethodNotSupportedException because it has not been called with a GET method. At least, this is what happened to me with spring-security-oauth2-2.0.13.RELEASE
public OAuth2AccessToken getAccessToken() throws HttpRequestMethodNotSupportedException {
HashMap<String, String> parameters = new HashMap<>();
parameters.put("client_id", CLIENT_ID);
parameters.put("client_secret", CLIENT_SECRET);
parameters.put("grant_type", "client_credentials");
ClientDetails clientDetails = clientDetailsStore.get(CLIENT_ID);
// Create principal and auth token
User userPrincipal = new User(CLIENT_ID, CLIENT_SECRET, true, true, true, true, clientDetails.getAuthorities());
UsernamePasswordAuthenticationToken principal = new UsernamePasswordAuthenticationToken(userPrincipal, CLIENT_SECRET,
clientDetails.getAuthorities());
ResponseEntity<OAuth2AccessToken> accessToken = tokenEndpoint.postAccessToken(principal, parameters);
return accessToken.getBody();
}
This has worked for me:
#Override public OAuth2AccessToken getToken(String username, String password) {
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("client_id", clientid);
parameters.put("grant_type", "password");
parameters.put("password", username);
parameters.put("scope", scope);
parameters.put("username", password);
AuthorizationRequest authorizationRequest = defaultOAuth2RequestFactory.createAuthorizationRequest(parameters);
authorizationRequest.setApproved(true);
OAuth2Request oauth2Request = defaultOAuth2RequestFactory.createOAuth2Request(authorizationRequest);
// Create principal and auth token
final UsernamePasswordAuthenticationToken loginToken = new UsernamePasswordAuthenticationToken(
username, password);
Authentication authentication = authenticationManager.authenticate(loginToken);
OAuth2Authentication authenticationRequest = new OAuth2Authentication(oauth2Request, authentication);
authenticationRequest.setAuthenticated(true);
OAuth2AccessToken accessToken = tokenServices.createAccessToken(authenticationRequest);
return accessToken;
}
In the Oauth2Configuration:
#Bean
DefaultOAuth2RequestFactory defaultOAuth2RequestFactory() {
return new DefaultOAuth2RequestFactory(clientDetailsService);
}
The rest of the Oauth2Configuration should look like in the article:
http://stytex.de/blog/2016/02/01/spring-cloud-security-with-oauth2/
Problem
I had problems with all the implementations listed here, so I finally managed to get my own with a stateless server, oauth2 and google social. Its just the last part of the tutorial that is missing here
The problem for me is that after executing the google oauth, I need to exchange a 10 second duration token for a long lived token. In order to do that I need to generate a JWT token and exchange it with a real access token generated by myself.
Implementation
#Service
class SocialTokenVerificationService {
#Autowired
private lateinit var jwsTokenService: JWSTokenService
#Autowired
private lateinit var clientDetailsService: ClientDetailsService
#Autowired
private lateinit var userService: UserService
#Autowired
private lateinit var tokenServices: DefaultTokenServices
#Autowired
private lateinit var tokenRequestFactory: OAuth2RequestFactory
fun verifyToken(token: String): OAuth2AccessToken? {
val claimSet = jwsTokenService.parseToken(token)
val userDetails = userService.loadUserByUsername(claimSet.subject)
val client = clientDetailsService.loadClientByClientId(DEFAULT_SERVER_CLIENT)
val parameters = HashMap<String, String>()
val authentication = UsernamePasswordAuthenticationToken(userDetails, null, userDetails.authorities)
return tokenServices.createAccessToken(OAuth2Authentication(
tokenRequestFactory.createOAuth2Request(client, TokenRequest(parameters, client.clientId, listOf("read", "write"), "password")),
authentication
))
}
}
JWSTokenService: its a self implemented class that encodes and decodes the exchanging token between google oauth and mine.
ClientDetailsService: bean declared as as part of the authorization server. Comes from my database
override fun configure(clients: ClientDetailsServiceConfigurer) {
clients.jdbc(datasource)
}
UserService: just a user service that extends UserDetailsService to obtain my users from the database
DefaultTokenServices: implemented as a primary bean as follows
#Bean
#Primary
fun tokenServices(): DefaultTokenServices {
val defaultTokenServices = DefaultTokenServices()
defaultTokenServices.setTokenStore(tokenStore())
defaultTokenServices.setSupportRefreshToken(true)
defaultTokenServices.setTokenEnhancer(jwtAccessTokenConverter())
return defaultTokenServices
}
OAuth2RequestFactory: implemented as a bean as follows
#Bean
fun oauthRequestFactory(clientsDetails: ClientDetailsService): OAuth2RequestFactory {
return DefaultOAuth2RequestFactory(clientsDetails)
}
With all this dependencies, what I need to do to generate a token that gets stored into the database and follows the same flows as the other ones without providing a password is:
Parse the jws token and verify its validity
Load the user that was authenticated with google
Generate an Authentication using the UsernamePasswordAuthenticationToken class. This is the key part, call DefaultTokenServices#createAccessToken to obtain a new token. It needs some arguments to execute the request:
OAuth2Request: it can be created with the OAuth2RequestFactory
The Authentication created previously
We need to generate a TokenRequest with the client that is triggering this token request. In my case I have that hardcoded
Summary
So to recap how to create a token manually:
We need to ask the token services to give us a token
For that we need to provide the authentication details and a client who does the request
With those 2 we can obtain a new token and serve it normally
In a spring boot 2.2.2 project I'm using the following code to do a pasword flow server side:
I had to specify authorizedClientManager.setContextAttributesMapper since PasswordOAuth2AuthorizedClientProvider is expecting specific attributes in the context. Hope that helps.
Config (application.yaml):
spring:
security:
oauth2:
client:
provider:
yourOauthProvider:
user-info-uri: ...
authorization-uri: ...
token-uri: ...
registration:
regId:
clientId: ...
clientSecret: ...
provider: yourOauthProvider
authorization-grant-type: password
redirect-uri-template: "{baseUrl}/login/oauth2/code/{registrationId}"
scope:
Wiring:
#Configuration
public class Oauth2ClientConfig {
#Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.password()
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager =
new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
authorizedClientManager.setContextAttributesMapper(r -> {
Map<String, Object> m = new HashMap<>();
m.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, r.getPrincipal().getPrincipal());
m.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, r.getPrincipal().getCredentials());
return m;
});
return authorizedClientManager;
}
}
Service:
class AuthService {
#Autowired
private OAuth2AuthorizedClientManager authorizedClientManager;
public OAuth2AccessToken authenticate(String user, String password) {
Authentication principal = new UsernamePasswordAuthenticationToken(
user,
password);
OAuth2AuthorizeRequest authorizeRequest =
OAuth2AuthorizeRequest.withClientRegistrationId("regId")
.principal(principal)
.build();
OAuth2AuthorizedClient authorizedClient =
this.authorizedClientManager.authorize(authorizeRequest);
return authorizedClient.getAccessToken();
}
}

How to automatically login as a user using Spring Security without knowing their password?

My application uses Spring Security, and my client requires:
users to be able to automatically login after signup.
an admin to login as any user without knowing their password.
So I need to figure out how to login as any user automatically without knowing their password.
How can this be accomplished using Spring Security?
To get this to work, I had to:
Configure a reference to the UserDetailsService (jdbcUserService)
<authentication-manager>
<authentication-provider>
<jdbc-user-service id="jdbcUserService" data-source-ref="dataSource"
users-by-username-query="select username,password, enabled from users where username=?"
authorities-by-username-query="select u.username, ur.authority from users u, user_roles ur where u.user_id = ur.user_id and u.username =? "
/>
</authentication-provider>
</authentication-manager>
Autowire my userDetailsManager in my controller:
#Autowired
#Qualifier("jdbcUserService") // <-- this references the bean id
public UserDetailsManager userDetailsManager;
In the same controller, authenticate my user like so:
#RequestMapping("/automatic/login/test")
public #ResponseBody String automaticLoginTest(HttpServletRequest request)
{
String username = "anyUserName#YourSite.com";
Boolean result = authenticateUserAndInitializeSessionByUsername(username, userDetailsManager, request);
return result.toString();
}
public boolean authenticateUserAndInitializeSessionByUsername(String username, UserDetailsManager userDetailsManager, HttpServletRequest request)
{
boolean result = true;
try
{
// generate session if one doesn't exist
request.getSession();
// Authenticate the user
UserDetails user = userDetailsManager.loadUserByUsername(username);
Authentication auth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
}
catch (Exception e)
{
System.out.println(e.getMessage());
result = false;
}
return result;
}
Note that a good precursor to just using spring security for your app can be found here.
for second problem
an admin to login as any user without knowing their password.
you should use switch user feature from spring. javadoc and article
This is answer to above question
In Controller:
#RequestMapping(value = "/registerHere", method = RequestMethod.POST)
public ModelAndView registerUser(#ModelAttribute("user") Users user, BindingResult result,
HttpServletRequest request, HttpServletResponse response) {
System.out.println("register 3");
ModelAndView mv = new ModelAndView("/home");
mv.addObject("homePagee", "true");
String uname = user.getUsername();
if (userDAO.getUserByName(uname) == null) {
String passwordFromForm = user.getPassword();
userDAO.saveOrUpdate(user);
try {
authenticateUserAndSetSession(user, passwordFromForm, request);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("register 4");
log.debug("Ending of the method registerUser");
return mv;
}
Further above method in controller is defined as:
`private void authenticateUserAndSetSession(Users user, String passwor`dFromForm, HttpServletRequest request){
String username = user.getUsername();
System.out.println("username: " + username + " password: " + passwordFromForm);
UserDetails userDetails = userDetailsService.loadUserByUsername(user.getUsername());
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, passwordFromForm, userDetails.getAuthorities());
request.getSession();
System.out.println("Line Authentication 1");
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetails(request));
System.out.println("Line Authentication 2");
Authentication authenticatedUser = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
System.out.println("Line Authentication 3");
if (usernamePasswordAuthenticationToken.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
System.out.println("Line Authentication 4");
}
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());// creates context for that session.
System.out.println("Line Authentication 5");
session.setAttribute("username", user.getUsername());
System.out.println("Line Authentication 6");
session.setAttribute("authorities", usernamePasswordAuthenticationToken.getAuthorities());
System.out.println("username: " + user.getUsername() + "password: " + user.getPassword()+"authorities: "+ usernamePasswordAuthenticationToken.getAuthorities());
user = userDAO.validate(user.getUsername(), user.getPassword());
log.debug("You are successfully register");
}
Other answers didnt suggest to put it in try/catch so one does not realize why logic is not working as code runs...and nothing is there neither error or exception on console. So if you wont put it in try catch you wont get exception of bad credentials.

Categories

Resources