当前位置: 首页 > 知识库问答 >
问题:

Spring Security性-未调用自定义userDetailsService实现

况喜
2023-03-14

尝试使用自定义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个答案

邢运良
2023-03-14

http的Spring Security配置中,应更改以下内容:

default-target-url="/abcd"

对某事

default-target-url="/"

或者你定义的任何东西。

  • default-target-url定义登录过程成功时的默认位置。
  • 确保定义所有必要的intercept-url从最特定到最通用
 类似资料:
  • 我试图为当前登录的用户添加一些自定义数据,所以我发现我可以实现自己的UserDetailsService并将其插入Spring中,但它从未被调用,我总是以用户名字符串的形式获得主体。 我有我的UserDetailsService实现: 我的UserDetails实现: 并尝试通过多种方式在config(SecurityConfiguration)中设置它:

  • 问题内容: 这是我的情况: 一个Web应用程序对许多应用程序执行某种SSO 登录的用户,而不是单击链接,该应用就会向正确的应用发布包含用户信息(名称,pwd [无用],角色)的帖子 我正在其中一个应用程序上实现SpringSecurity以从其功能中受益(会话中的权限,其类提供的方法等) 因此,我需要开发一个 自定义过滤器 -我猜想-能够从请求中检索用户信息,通过自定义 DetailsUserSe

  • 我正在尝试从基于Spring XML的配置迁移到纯Java配置,我已经配置了所有配置文件,但当我尝试在登录页面中输入用户名和密码时,它会再次将我重定向回登录页面。我相信userServiceImpl方法没有被调用,因为控件没有被调用。在这里,我有一个自动连接的userServiceImpl方法,它实现了Spring Security核心凭据的UserDetailsService。 自定义身份验证成

  • 在我的Spring Boot项目中,我创建了一个自定义注释,其中validator扩展了ConstraintValidator,以验证RequestBody中的一些字段。注释对于非嵌套字段可以很好地工作,但对于嵌套字段不调用验证器。 我的注释如下所示: 我的验证类: 它在这样的情况下工作正常: 但是当放在嵌套对象上时,不会调用验证器: 类在我的中的用法: 关于如何解决这个问题有什么想法吗?我已经尝

  • 我们使用Spring Security OAuth2保护我们的REST服务(用于服务器到服务器通信,不涉及用户)。但是,当您尝试访问浏览器中的受保护资源时,它将显示: 我们希望这是我们自己选择的自定义页面。有办法吗? 设置“拒绝访问”页面不起作用。首先,它需要定义一个登录页面,我们没有,因为这是一个纯服务器到服务器的通信。另一个原因是,这个属性自Spring 3.0..或类似的版本以来就被弃用了。

  • 这是我设置适配器的方式: 我正在寻找一个解决方案,从昨天开始,我已经阅读了所有关于StackOverflow的帖子,但没有一个与我的问题相匹配。所以我想知道,它是否可以来自LinkedHashMap<...> 编辑:这是我的布局r.layout.etat_piece_item