Spring security - 未调用自定义 userDetailsService 实现
Posted
技术标签:
【中文标题】Spring security - 未调用自定义 userDetailsService 实现【英文标题】:Spring security - custom userDetailsService implemenation not getting called 【发布时间】:2016-03-09 16:47:59 【问题描述】:尝试使用自定义 userDetailsService 学习 Spring Security 并面临以下问题
当访问受限页面(/admin 或 /user)时,spring security 会启动并显示登录页面。 但是在使用正确的用户名和密码提交登录页面后,在调用我的自定义 userDetailsService 实现中的 loadUserByUsername 方法之前直接显示拒绝访问页面。
在日志中,只有 org.springframework.security.access.AccessDeniedException
异常 - 在访问受限页面时,没有其他异常。
代码
@Controller
public class TestController
@RequestMapping("/home")
public String getHomePage()
return "home";
@RequestMapping(value="/user")
public String getUserPage()
return "user";
@RequestMapping(value="/admin")
public String getAdminPage()
return "admin";
安全配置:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/" access="permitAll"/>
<intercept-url pattern="/login" access="permitAll"/>
<intercept-url pattern="/logout" access="permitAll"/>
<intercept-url pattern="/denied" access="hasRole('ROLE_USER')"/>
<intercept-url pattern="/user" access="hasRole('ROLE_USER')"/>
<intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')"/>
<form-login login-page="/login"
username-parameter="tmp_usrnm"
password-parameter="tmp_pwd"
authentication-failure-url="/login/failure"
default-target-url="/abcd"/>
<access-denied-handler error-page="/denied"/>
<logout invalidate-session="true"
logout-success-url="/logout/success"
logout-url="/logout"/>
</http>
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder hash="md5"/>
</authentication-provider>
</authentication-manager>
<beans:bean id="customUserDetailsService" class="com.krishnan.balaji.mc.service.CustomUserDetailsService">
<beans:property name="userRepository">
<beans:bean class="com.krishnan.balaji.mc.repos.UserRepositoryImpl"></beans:bean>
</beans:property>
</beans:bean>
登录表格:
<!--<form class="login-form" action=<c:url value="j_spring_security_check"/> method="post" >-->
<form action=<c:url value="/login"/> method="post" >
<input id="j_username" name="tmp_usrnm" size="20" maxlength="50" type="text"/>
<input id="j_password" name="tmp_pwd" size="20" maxlength="50" type="password"/>
<p><input type="submit" value="Login"/></p>
</form>
控制器为登录/注销/访问被拒绝页面提供服务
@Controller
public class UserAccessController
@RequestMapping("/login")
public String login(Model model, @RequestParam(required=false) String message)
model.addAttribute("message", message);
System.out.println("serving login page");
return "access/login";
@RequestMapping(value = "/denied")
public String denied()
System.out.println("serving access denied page");
return "access/denied";
@RequestMapping(value = "/login/failure")
public String loginFailure()
System.out.println("serving failed login page");
String message = "Login Failure!";
return "redirect:/login?message="+message;
@RequestMapping(value = "/logout/success")
public String logoutSuccess()
System.out.println("serving logout page");
String message = "Logout Success!";
return "redirect:/login?message="+message;
CustomUserDetailsService
@Service
public class CustomUserDetailsService implements UserDetailsService
private UserRepository userRepository;;
@Transactional(readOnly = true)
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException
System.out.println("loadUserByUsername called");
try
com.krishnan.balaji.mc.model.User domainUser = userRepository
.getUserByUserName(username);
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
return new User(domainUser.getUsername(), domainUser.getPassword()
.toLowerCase(), enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked,
getAuthorities(domainUser.getRole().getRole()));
catch (Exception e)
throw new RuntimeException(e);
public Collection<? extends GrantedAuthority> getAuthorities(Integer role)
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
return authList;
public List<String> getRoles(Integer role)
List<String> roles = new ArrayList<String>();
if (role.intValue() == 1)
roles.add("ROLE_USER");
roles.add("ROLE_ADMIN");
else if (role.intValue() == 2)
roles.add("ROLE_USER");
return roles;
public static List<GrantedAuthority> getGrantedAuthorities(
List<String> roles)
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles)
authorities.add(new SimpleGrantedAuthority(role));
return authorities;
public UserRepository getUserRepository()
return userRepository;
public void setUserRepository(UserRepository userRepository)
this.userRepository = userRepository;
【问题讨论】:
【参考方案1】:在 http
的 Spring Security 配置中,您应该更改以下内容:
default-target-url="/abcd"
类似
default-target-url="/"
或您定义的任何其他内容。
default-target-url
定义了在登录过程succeeds 时默认 去哪里。
确保定义所有必要的intercept-url
,从最具体到最通用
【讨论】:
也尝试将其更改为 /home.. 无论如何,这只有在登录过程成功的情况下 - 在我的情况下,甚至没有调用 userdetailsService以上是关于Spring security - 未调用自定义 userDetailsService 实现的主要内容,如果未能解决你的问题,请参考以下文章
Spring security - 未调用自定义 userDetailsService 实现
Spring Security:未调用自定义 UserDetailsService(使用 Auth0 身份验证)
未调用 Spring Security j_spring_security_check
Spring安全性j_spring_security_check调用给出404未找到错误[关闭]