0

ユーザーがログインしていない間はログインページにのみアクセスでき、他のもの(リソースを除く)にはアクセスできないアプリケーションを作成しようとしています。ログインしたら、ログアウトするまでログインページにアクセスできず、他のすべてのページにアクセスできないようにしたいと思います。現在、私のサービスは、私がすでにログインしているときに私を覚えていますが、それでもログイン ページにアクセスできます。ログイン コントローラーでユーザーを識別しようとすると、認証は常に null になります。

私が使用していることに注意してください:Spring MVC 3 Hibernate 4 Groovy 2.1

これが私のログインコントローラーです:

    @RequestMapping(method = RequestMethod.GET)
String login(Model model, @RequestParam(value="account", required=false) String account, @RequestParam(value="uuid", required=false) String uuid, @RequestParam(value="message", required=false) String message) {
    addStatusAttribute(model, account, uuid, message)
    model.addAttribute("newUser", new User())
    Authentication auth = SecurityContextHolder.context.authentication
    if (auth != null) {
        logger.info(auth.name)
    }
    else {
        logger.info(auth) // Always hits here
    }
    if (!(auth instanceof AnonymousAuthenticationToken) && auth != null) {
        "forward:/home"
    }
    else {
        "login"
    }

これが私のセキュリティ設定です:

<http auto-config="true">
            <intercept-url pattern ="/login**" filters="none"/>
    <intercept-url pattern="/static/**" filters="none" />
    <intercept-url pattern="/**" access="ROLE_USER" />
    <form-login login-page="/login" default-target-url="/home"
        authentication-failure-url="/login?error=true"
        always-use-default-target="true" />
    <logout logout-success-url="/login" />
    <remember-me data-source-ref="dataSource"
        user-service-ref="myUserDetailsManager"
        token-validity-seconds="864000"
        key="skyfury_key"/>
</http>

これに問題はないと思いますが、私の JSP フォームは次のとおりです。

                    <form method="POST" action="<c:url value="/j_spring_security_check" />">
                <input type="text" name="j_username" placeholder="Email" />
                <input type="password" name="j_password" placeholder="Password" />
                <label for="j_remember">Remember Me</label>
                <input id="j_remember" type='checkbox' name='_spring_security_remember_me' value="on" />
                <input type="submit" value="Login" />
            </form>

できれば助けてください!私はこれをずっと見つめていました!! ありがとう :)

4

2 に答える 2

0

問題は、filters="none" にマッピングしている /login URL です。これは、SecurityContext と Authentication がその URL で利用できないことを意味します。以下に示すように、構成を変更してみてください。

<http auto-config="true" use-expressions="true">
    <intercept-url pattern ="/login**" access="permitAll"/>
    <intercept-url pattern="/static/**" access="permitAll" />
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
    <form-login login-page="/login" default-target-url="/home"
        authentication-failure-url="/login?error=true"
        always-use-default-target="true" />
    <logout logout-success-url="/login" />
    <remember-me data-source-ref="dataSource"
        user-service-ref="myUserDetailsManager"
        token-validity-seconds="864000"
        key="skyfury_key"/>
</http>

3 つの変更を行ったことに気付くでしょう。

  1. 最初にuse-expressions="true"と述べました。これにより、アクセス属性で SpELを使用できます。SpEL を許可することで、構成がより強力になり、「permitAll」を使用してすべてのユーザーがリソースにアクセスできることを示すことができます。「permitAll」の使用は、Spring Security がこのリクエストに対して引き続き動作するが、すべてのユーザーがリクエストにアクセスできるという点で、 filters="none"とは異なります。これは、permitAll にマップされたリクエストに対して SecurityContextHolder が設定されることを意味します。

  2. 2 番目の変更は、permitAll にマップされるように「/login」URL を変更することです。繰り返しますが、これは、permitAll にマップされたリクエストに対して SecurityContextHolder が設定されることを意味します。

  3. 最後の変更は、use-expressions="true" の変更で機能するように、他のアクセス属性が更新されたことです。特に「ROLE_USER」は機能しません。代わりに、"hasRole('ROLE_USER')" を指定する必要があります。

認証に直接アクセスする代わりに、次を使用することも検討します。これにより、Spring Security に密結合されていないことが保証されます。

@RequestMapping(method = RequestMethod.GET)
String login(Principal principal, Model model, @RequestParam(value="account", required=false) String account, @RequestParam(value="uuid", required=false) String uuid, @RequestParam(value="message", required=false) String message) {
    ...

    logger.info(principal?.name)

    if (principal != null) {
        "forward:/home"
    }
    else {
        "/login"
    }
}

これは、Spring MVC がプリンシパルをHttpServletRequest.userPrincipalで見つかった値に自動的に解決するために機能します。認証が匿名でない場合、Spring Security は HttpServletRequest.userPrincipal を現在の Authentication オブジェクトに置き換えるため、これは透過的に機能します。

于 2013-10-15T12:50:13.483 に答える