Java tutorial
/** * Copyright 2014 tgrape Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ph.fingra.statisticsweb.security; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider; import org.springframework.security.authentication.dao.SaltSource; import org.springframework.security.authentication.encoding.PasswordEncoder; import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.util.Assert; import ph.fingra.statisticsweb.common.MemberJoinstatus; import ph.fingra.statisticsweb.common.MemberRole; import ph.fingra.statisticsweb.common.MemberStatus; import ph.fingra.statisticsweb.domain.Member; import ph.fingra.statisticsweb.service.MemberService; @SuppressWarnings("deprecation") public class FingraphAnthenticationProvider extends AbstractUserDetailsAuthenticationProvider { private Logger logger = LoggerFactory.getLogger(getClass()); private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword"; private PasswordEncoder passwordEncoder; // password encoder for admin.properties private org.springframework.security.crypto.password.PasswordEncoder adminPasswordEncoder; private String userNotFoundEncodedPassword; private SaltSource saltSource; private MemberService memberService; // admin.properties values @Value("#{fingraphAdminAuth.email}") private String adminEmail; @Value("#{fingraphAdminAuth.name}") private String adminName; @Value("#{fingraphAdminAuth.password}") private String adminPassword; public FingraphAnthenticationProvider() { setPasswordEncoder(new PlaintextPasswordEncoder()); } @Override protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { Object salt = null; if (this.saltSource != null) { salt = this.saltSource.getSalt(userDetails); } if (authentication.getCredentials() == null) { logger.debug("Authentication failed: no credentials provided"); throw new BadCredentialsException( messages.getMessage("Invalid user id or password. Please try again.", "Bad credentials"), userDetails); } String presentedPassword = authentication.getCredentials().toString(); logger.debug("userDetails {}, presentedPassword {}", userDetails, presentedPassword); if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, salt)) { logger.debug("Authentication failed: password does not match stored value"); //throw new BadCredentialsException( // messages.getMessage("Invalid user id or password. Please try again.", "Bad credentials"), // userDetails); throw new PasswordMissmatchUserException("Invalid user id or password. Please try again.", userDetails); } FingraphUser member = (FingraphUser) userDetails; if (MemberStatus.valueOf(member.getStatus()) != MemberStatus.ACTIVE) { logger.debug("Authentication failed: un-active user"); throw new UnverifiedUserException("AbstractUserDetailsAuthenticationProvider.disabled", userDetails); } if (MemberJoinstatus.valueOf(member.getJoinstatus()) != MemberJoinstatus.APPROVAL) { logger.debug("Authentication failed: un-approval user"); throw new UnapprovalUserException("AbstractUserDetailsAuthenticationProvider.disabled", userDetails); } } protected void doAfterPropertiesSet() throws Exception { Assert.notNull(this.memberService, "A MemberService must be set"); Assert.notNull(this.passwordEncoder, "A PasswordEncoder must be set"); } @SuppressWarnings("unused") @Override protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { // admin.properties values logger.debug("[adminEmail] {}", adminEmail); logger.debug("[adminName] {}", adminName); logger.debug("[adminPassword] {}", adminPassword); UserDetails loadedUser = null; try { logger.debug("retrieveUser {}", username); Member member = null; if (username.equals(adminEmail)) { member = new Member(); member.setEmail(adminEmail); member.setName(adminName); member.setPassword(adminPassword); member.setStatus(MemberStatus.ACTIVE.getValue()); member.setJoinstatus(MemberJoinstatus.APPROVAL.getValue()); member.setRole(MemberRole.ROLE_ADMIN.getValue()); } else { member = memberService.get(username); } if (member == null) { throw new UsernameNotFoundException("Not found user id"); } // lastlogin update if (member.getRole() == MemberRole.ROLE_USER.getValue()) { memberService.updateMemberLastLoginTime(member); } if (member.getRole() == MemberRole.ROLE_ADMIN.getValue()) { //logger.debug("passwordEncoder {}", adminPasswordEncoder); loadedUser = new FingraphUser(member, adminPasswordEncoder); } else { loadedUser = new FingraphUser(member); } logger.debug("userDetail is {}", loadedUser.toString()); } catch (UsernameNotFoundException notFound) { if (authentication.getCredentials() != null) { String presentedPassword = authentication.getCredentials().toString(); passwordEncoder.isPasswordValid(userNotFoundEncodedPassword, presentedPassword, null); } throw notFound; } catch (Exception repositoryProblem) { throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem); } if (loadedUser == null) { throw new AuthenticationServiceException( "UserDetailsService returned null, which is an interface contract violation"); } return loadedUser; } @Autowired public void setPasswordEncoder(Object passwordEncoder) { Assert.notNull(passwordEncoder, "passwordEncoder cannot be null"); if (passwordEncoder instanceof PasswordEncoder) { setPasswordEncoder((PasswordEncoder) passwordEncoder); return; } if (passwordEncoder instanceof org.springframework.security.crypto.password.PasswordEncoder) { final org.springframework.security.crypto.password.PasswordEncoder delegate = (org.springframework.security.crypto.password.PasswordEncoder) passwordEncoder; // password encoder for admin.properties adminPasswordEncoder = delegate; setPasswordEncoder(new PasswordEncoder() { public String encodePassword(String rawPass, Object salt) { checkSalt(salt); return delegate.encode(rawPass); } public boolean isPasswordValid(String encPass, String rawPass, Object salt) { checkSalt(salt); return delegate.matches(rawPass, encPass); } private void checkSalt(Object salt) { Assert.isNull(salt, "Salt value must be null when used with crypto module PasswordEncoder"); } }); return; } throw new IllegalArgumentException("passwordEncoder must be a PasswordEncoder instance"); } private void setPasswordEncoder(PasswordEncoder passwordEncoder) { Assert.notNull(passwordEncoder, "passwordEncoder cannot be null"); this.userNotFoundEncodedPassword = passwordEncoder.encodePassword(USER_NOT_FOUND_PASSWORD, null); this.passwordEncoder = passwordEncoder; } protected PasswordEncoder getPasswordEncoder() { return passwordEncoder; } public void setSaltSource(SaltSource saltSource) { this.saltSource = saltSource; } protected SaltSource getSaltSource() { return saltSource; } public MemberService getMemberService() { return memberService; } @Autowired protected void setMemberService(MemberService memberService) { this.memberService = memberService; } }