Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java @ModelAttribute不适用于spring安全性_Java_Spring_Jsp_Spring Mvc_Spring Security - Fatal编程技术网

Java @ModelAttribute不适用于spring安全性

Java @ModelAttribute不适用于spring安全性,java,spring,jsp,spring-mvc,spring-security,Java,Spring,Jsp,Spring Mvc,Spring Security,当登录失败时,我试图重定向登录页面上输入的用户名,但在我的控制器中,从“@modeldattribute(“user”)”检索到的用户用户名为空。当我不使用spring安全性时,这是有效的 我假设表单实际上首先发布到SpringSecurity,然后它被重定向到控制器,所以输入的信息在SpringSecurity之间丢失 如何检索用户而不将其发送到链接参数 PS:我尝试为“/loginFailed”创建一个控制器,如果登录失败,则将其发送到该控制器,并在该控制器上使用method=Request

当登录失败时,我试图重定向登录页面上输入的用户名,但在我的控制器中,从“@modeldattribute(“user”)”检索到的用户用户名为空。当我不使用spring安全性时,这是有效的

我假设表单实际上首先发布到SpringSecurity,然后它被重定向到控制器,所以输入的信息在SpringSecurity之间丢失

如何检索用户而不将其发送到链接参数

PS:我尝试为“/loginFailed”创建一个控制器,如果登录失败,则将其发送到该控制器,并在该控制器上使用method=RequestMethod.POST

登录控制器

@RequestMapping(value = "/login", method = RequestMethod.GET)
    public String listPersons(@ModelAttribute("user") User u, @RequestParam(required = false) String authfailed, String logout,
            String denied, Model model) {
        model.addAttribute("user", u);
        String message = "";
        if (authfailed != null) {
            message = "Invalid username or password, try again !";
        } else if (logout != null) {
            message = "Logged Out successfully, login again to continue !";
        } else if (denied != null) {
            message = "Access denied for this user !";
        }
        model.addAttribute("error", message);
        return "login";
    }

login.jsp

<c:url var="trylogin" value="/j_spring_security_check" ></c:url>
<c:url var="register" value="/register" ></c:url>

<div id="login-box">
    <form:form action="" modelAttribute="user" method="POST">
        <table>
            <tr>
                <td> <form:label path="username"> <spring:message text="Username: "/> </form:label> </td>
                <td> <form:input path="username" /> </td> 
            </tr>
            <tr>
                <td> <form:label path="password"> <spring:message text="Password: "/> </form:label> </td>
                <td> <form:password path="password" /> </td> 
            </tr>
            <tr>
                <td> <input type="submit" value="<spring:message text="Login"/>"
                                    onclick="document.getElementById('user').setAttribute('action', '${trylogin}')"/> </td>
                <td> <input type="submit" value="<spring:message text="Register"/>"
                                    onclick="document.getElementById('user').setAttribute('action', '${register}')"/> </td>
            </tr>
        </table>
    </form:form>
    <c:if test="${not empty error}">
        <div class="error">${error}</div>
    </c:if>
</div>

您应该使用AuthenticationFailureHandler。出于您的目的,声明Spring SimpleRuthenticationFailureHandler类的bean并指定将请求转发到目标URL,而不是配置中的默认重定向行为就足够了。这样,您的登录控制器将可以访问原始请求,包括用户名

文件:

资料来源:


然后在您的表单登录规范中:

<security:form-login 
    ...
    authentication-failure-handler-ref="failureHandler"
    ...
/> 

这是一种错误的方式。登录页控制器仅用于查看此页。对于检查凭证,您需要创建服务,例如:

@Service("adminDetailsServiceImpl")
public class AdminDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private SepAdminDao adminDao;

    @Override
    public UserDetails loadUserByUsername(String login) {
        SepAdmin admin;

        if (StringUtils.isBlank(login))
            throw new UsernameNotFoundException("Admin not found!");
        admin = adminDao.findByEmail(login);
        return new org.springframework.security.core.userdetails.User(
                admin.getEmail(),
                admin.getPassword(),
                getGrantedAuthorities(admin.getRole().getPermissionNames()));
    }

    private static List<GrantedAuthority> getGrantedAuthorities(String[] roles) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String role : roles)
            authorities.add(new SimpleGrantedAuthority(role));
        return authorities;
    }
}
@Service(“adminDetailsServiceImpl”)
公共类AdminDetailsServiceImpl实现UserDetailsService{
@自动连线
私人行政区;
@凌驾
公共用户详细信息loadUserByUsername(字符串登录){
SepAdmin-admin;
if(StringUtils.isBlank(登录))
抛出新的UsernameNotFoundException(“找不到管理员!”);
admin=adminDao.findByEmail(登录);
返回新的org.springframework.security.core.userdetails.User(
admin.getEmail(),
admin.getPassword(),
GetGrantedAuthories(admin.getRole().getPermissionNames());
}
私有静态列表GetGrantedAuthories(字符串[]角色){
列表权限=新建ArrayList();
for(字符串角色:角色)
添加(新的SimpleGrantedAuthority(角色));
返回当局;
}
}
使用spring分配此服务(例如,我查看了我的简单安全配置):


PERM\u ROOT>PERM\u CREATE\u管理员
PERM\u创建\u管理员>PERM\u删除\u管理员
PERM\u DELETE\u ADMINS>PERM\u EDIT\u ADMINS
PERM\u编辑\u管理员>PERM\u查看\u管理员
PERM\u ROOT>PERM\u CREATE\u角色
PERM\u创建\u角色>PERM\u删除\u角色
PERM\u DELETE\u ROLES>PERM\u EDIT\u ROLES
PERM\u编辑\u角色>PERM\u查看\u角色
然后,当用户提交登录表单时,我们重定向到/j_spring_security_check,检查我们的服务在何处使用,如果出现登录异常,我们可以在登录jsp页面进行检查:

<!-- spring_exception -->
<c:if test="${not empty SPRING_SECURITY_LAST_EXCEPTION}">
    <p class="alert alert-danger alert-dismissable">
        <spring:message code="Error.Msg.Login"/>
    </p>
    <br/>
</c:if>


如果成功,我们将重定向到默认的目标url,在我的例子中是根

 <form-login username-parameter="email"
         password-parameter="password"
         login-page="/login" default-target-url="/" authentication-failure-url="/login?failed"/>

这就是为什么浏览器上的链接保持为“/j_spring_security_check”

@Service("adminDetailsServiceImpl")
public class AdminDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private SepAdminDao adminDao;

    @Override
    public UserDetails loadUserByUsername(String login) {
        SepAdmin admin;

        if (StringUtils.isBlank(login))
            throw new UsernameNotFoundException("Admin not found!");
        admin = adminDao.findByEmail(login);
        return new org.springframework.security.core.userdetails.User(
                admin.getEmail(),
                admin.getPassword(),
                getGrantedAuthorities(admin.getRole().getPermissionNames()));
    }

    private static List<GrantedAuthority> getGrantedAuthorities(String[] roles) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String role : roles)
            authorities.add(new SimpleGrantedAuthority(role));
        return authorities;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">
    <beans:bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
        <beans:property name="hierarchy">
            <beans:value>
                <!--Admin-->
                PERM_ROOT > PERM_CREATE_ADMINS
                PERM_CREATE_ADMINS > PERM_DELETE_ADMINS
                PERM_DELETE_ADMINS > PERM_EDIT_ADMINS
                PERM_EDIT_ADMINS > PERM_VIEW_ADMINS
                <!--Role-->
                PERM_ROOT > PERM_CREATE_ROLES
                PERM_CREATE_ROLES > PERM_DELETE_ROLES
                PERM_DELETE_ROLES > PERM_EDIT_ROLES
                PERM_EDIT_ROLES > PERM_VIEW_ROLES
            </beans:value>
        </beans:property>
    </beans:bean>
    <beans:bean id="expressionHandler"
                class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
        <beans:property name="roleHierarchy" ref="roleHierarchy"/>
    </beans:bean>
    <beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <beans:property name="decisionVoters">
            <beans:list>
                <beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
                    <beans:property name="expressionHandler" ref="expressionHandler"/>
                </beans:bean>
            </beans:list>
        </beans:property>
    </beans:bean>
    <beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
        <beans:constructor-arg ref="roleHierarchy"/>
    </beans:bean>
    <beans:bean id="passwordEncoder"
                class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
        <beans:constructor-arg value="10"/>
    </beans:bean>
    <http pattern="/resources/js/vendor/language" security="none"/>
    <http pattern="/favicon.ico" security="none"/>
    <http auto-config="true" use-expressions="true" access-denied-page="/403"
          access-decision-manager-ref="accessDecisionManager">
        <intercept-url pattern="/login" access="permitAll"/>
        <!--Admin-->
        <intercept-url pattern="/dashboard" access="hasRole('PERM_ROOT')"/>
        <intercept-url pattern="/admin/create_admin" access="hasRole('PERM_CREATE_ADMINS')"/>
        <intercept-url pattern="/admin/users/*/edit_admin" access="hasRole('PERM_EDIT_ADMINS')"/>
        <intercept-url pattern="/admin/users/*/view_admin" access="hasRole('PERM_VIEW_ADMINS')"/>
        <intercept-url pattern="/admin/users/*/delete_admin" access="hasRole('PERM_DELETE_ADMINS')"/>
        <!--Role-->
        <intercept-url pattern="/role/create_role" access="hasRole('PERM_CREATE_ROLES')"/>
        <intercept-url pattern="/role/*/edit_role" access="hasRole('PERM_EDIT_ROLES')"/>
        <intercept-url pattern="/role/*/view_role" access="hasRole('PERM_VIEW_ROLES')"/>
        <intercept-url pattern="/role/*/delete_role" access="hasRole('PERM_DELETE_ROLES')"/>
        <!--Route-->
        <form-login username-parameter="email"
                    password-parameter="password"
                    login-page="/login" default-target-url="/" authentication-failure-url="/login?failed"/>
        <logout logout-url="/logout" logout-success-url="/login"/>
    </http>
    <authentication-manager alias="authManager">
        <authentication-provider user-service-ref="adminDetailsServiceImpl">
            <password-encoder ref="passwordEncoder"/>
        </authentication-provider>
    </authentication-manager>
</beans:beans>
<!-- spring_exception -->
<c:if test="${not empty SPRING_SECURITY_LAST_EXCEPTION}">
    <p class="alert alert-danger alert-dismissable">
        <spring:message code="Error.Msg.Login"/>
    </p>
    <br/>
</c:if>
 <form-login username-parameter="email"
         password-parameter="password"
         login-page="/login" default-target-url="/" authentication-failure-url="/login?failed"/>