2017-01-12 22 views
0

私はApache ShiroでJavaのHibernateをユーザのログインと認証に使用しています。私はこのコードを使用してユーザーを認証し、意図したとおりに動作します(私が知る限り)。Apache Shiroのログイン認証でJavaの休止状態が「正常に」ログインした後にfalseを返す

try { 
     AuthenticationToken token = new UsernamePasswordToken(user.getUsername().toUpperCase(), user.getPassword()); 


     Subject currentUser = SecurityUtils.getSubject(); 

     Session session = currentUser.getSession(); 
     session.setAttribute("username", user.getUsername()); 
     System.out.println("USER: " + session.getAttribute("username")); 

     currentUser.login(token); 

     System.out.println("User [" + currentUser.getPrincipal() + "] logged in successfully."); 
     System.out.println("Is user authenticated? " + currentUser.isAuthenticated()); 
    } 
    catch (ExcessiveAttemptsException eae) { 
     eae.getStackTrace(); 
     eae.printStackTrace(); 
    } 
    catch (AuthenticationException e) { 
     throw new ForbiddenException(); 
    } 

これは、正しい資格情報が提供されているか、不正な場合に禁止された例外が返された場合に機能します。

私は別の方法を使用してユーザーが承認されているかどうかを確認した後、常にfalse(真である必要がある場合)を返します。私はこれを引き起こしているのか分からない。デバッグモードでチェックする際

try { 
     Subject currentUser = SecurityUtils.getSubject(); 

     return SecurityUtils.getSubject().isAuthenticated(); 

    } catch (AuthenticationException e) { 
     throw new ForbiddenException(); 
    } 

あるCurrentUserはnullです。

別のアプローチを使用することもできますが、2行目にnullPointerExceptionを返します。

try { 

     sessionFactory.getCurrentSession().getTransaction().begin(); 

     User user = userDAO.find(securityContext.getUserPrincipal().getName()); 

     if (user == null) { 
      sessionFactory.getCurrentSession().getTransaction().rollback(); 
      throw new NotFoundException(); 
     } 

     UserModel result = new UserModel(user); 

     sessionFactory.getCurrentSession().getTransaction().commit(); 

     return result; 
} 
    } catch (HibernateException e) { 
     e.printStackTrace(); 
     sessionFactory.getCurrentSession().getTransaction().rollback(); 
    } 
    return null; 

私はshiro.iniを使用してローカルデータベースに接続します。
[更新]有効になっている(サーブレットを使用している)ときに自動的にログインできるデバッグログインフィルタを追加しました。意図したとおりに動作します。

私はURLセクションを追加しました。これはauthcBasicを使用すると動作しますが、Shiroのauthcを使用すると動作しません。メソッドisAuthenticated()またはgetCurrentUser()を呼び出すことで確認できます。 authcBasicを使用するとすべての正しい情報が返されますが、authcはfalse/nullを返します。 authcBasicを使用しているときにWebブラウザをクリーンアップしない限り、ログアウトできません。メソッドSecurityUtils.getSubject().logout();は、isAuthenticatedブール値をfalseに設定しますが(デバッグ時)、セッションに実際の効果はないようです。

# ======================= 
# Shiro INI configuration 
# ======================= 

[main] 
# Debug filter to automatically login 
debugLogin = util.DebugLoginFilter 
debugLogin.enabled = false 
debugLogin.username = ADMIN 
debugLogin.password = ADMIN 

jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm 
jdbcRealm.authenticationQuery = select password from user where username = ? 
jdbcRealm.userRolesQuery = select role from user_role INNER JOIN user ON  user_role.id = user.user_role_id where user.username = ? 

# Datasource for the jdbc realm 
ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource 
ds.serverName = localhost 
ds.user = root 
ds.databaseName = database 
jdbcRealm.dataSource = $ds 

authc.usernameParam = username 
authc.passwordParam = password 
authc.failureKeyAttribute = shiroLoginFailure 

sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher 
jdbcRealm.credentialsMatcher = $sha256Matcher 

[roles] 
admin = * 

[urls] 
/= debugLogin, authcBasic 
/index.html = debugLogin, authcBasic 
/api/login = anon 
/api/login/me = authcBasic 
/api/login/logout = authcBasic 
/api/** = debugLogin, authcBasic 

私のpom.xml

<dependency> 
    <groupId>org.apache.shiro</groupId> 
    <artifactId>shiro-core</artifactId> 
    <version>1.3.2</version> 
</dependency> 
<dependency> 
    <groupId>org.apache.shiro</groupId> 
    <artifactId>shiro-web</artifactId> 
    <version>1.3.2</version> 
</dependency> 

私のweb.xml

<listener> 
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class> 
</listener> 

<filter> 
    <filter-name>ShiroFilter</filter-name> 
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>ShiroFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
    <dispatcher>REQUEST</dispatcher> 
    <dispatcher>FORWARD</dispatcher> 
    <dispatcher>INCLUDE</dispatcher> 
    <dispatcher>ERROR</dispatcher> 
</filter-mapping> 

謝罪、私はミスをした場合、私はここに新たなんです!どんな助けでも大歓迎です。

編集:Apacheサーバを実行している場合に、このメッセージがコンソールに表示されます。

[localhost-startStop-1] INFO org.apache.shiro.config.IniSecurityManagerFactory - Realms have been explicitly set on the SecurityManager instance - auto-setting of realms will not occur. 
+0

あなたのアプリケーションでSecurityUtils.getSubject()を呼び出している場所。それは失敗ですか?同じリクエストか別のリクエストですか?あなたはフィルタまたは生成されたスレッド内から呼びますか? – teacurran

+0

こんにちは@teacurran私はフロントエンドから(Angular 2を使用して)POST要求として、Javaバックエンドにユーザー名とパスワードを渡して呼び出しています。 SecurityUtils.getSubject(); (私はコードをデバッグするときにすべての正確な情報を表示します)、実際にログイン/認証されたかどうかをチェックするフロントエンドから再度呼び出すと機能しません。 – ToDo

+0

が正しい。あなたはあなたのREST APIサービスを打つGETリクエストを呼び出しています。フィルターを使用してRESTサービスをどのように処理しますか?サーブレット?フィルタを使用すると、shiroフィルタの前に呼び出されている可能性があります。 – teacurran

答えて

0

私は解決策を発見しました。問題はコードではなく、私が使用したアプローチでした。

フロントエンドにはAngular 2を、バックエンドにはJava Hibernateを使用しています。 Shiroは別のディレクトリにあるため、フロントエンドと通信できません。しかし、それは角のあるアプリケーションを構築し、distコンテンツをバックエンドのWebContentにコピーした後で動作するはずです。

私は開発時に手動でログインするためにデバッグログインフィルタを使用します(プロダクションの準備ができたら、Shiroで無効にします)。

他の誰かがこの問題を抱えている場合に備えて、コードスニペットを保存します。

+0

'currentUser.login()'を実行すると、実際には、クライアント側が提供する 'username'と' password'をサーバ側のデータベースに格納されているものと照合するシステムがありますか? –

関連する問題