我正在使用Java Hibernate和Apache Shiro進行用戶登錄和驗證。我使用這段代碼來驗證用戶,並按預期工作(據我所知)。使用Apache Shiro登錄驗證的Java Hibernate在「成功」登錄後返回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(當它應該是true)。我不確定是什麼原因造成的。
try {
Subject currentUser = SecurityUtils.getSubject();
return SecurityUtils.getSubject().isAuthenticated();
} catch (AuthenticationException e) {
throw new ForbiddenException();
}
的currentUser在調試模式下檢查時爲空。
我也可以使用其他方法,但它會在第二行中返回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連接到本地數據庫。
[更新]我添加了一個調試登錄過濾器,它可以在啓用時自動登錄(使用Servlet)並且它按預期工作。
我已經添加了一個URL部分,它在我使用authcBasic時有效,但當我在Shiro中使用authc時不起作用。我可以通過調用方法isAuthenticated()
或getCurrentUser()
進行檢查。使用authcBasic返回所有正確的信息,但authc返回false/null。除非我清理Web瀏覽器,否則在使用authcBasic時我也無法註銷。方法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.
在你的應用程序中你調用SecurityUtils.getSubject();那是失敗的?相同的請求或其他請求?你是從過濾器還是派生的線程中調用它? – teacurran
嗨@teacurran我從前端調用它(使用Angular 2)作爲POST請求傳遞用戶名和密碼到Java後端。 SecurityUtils.getSubject();當它用於登錄時(它在調試代碼時顯示所有正確的細節)時工作,但是當我從前端再次調用它以檢查用戶是否實際登錄/認證時,它不起作用。 – ToDo
沒錯。所以你正在調用一個GET請求來打你的REST api服務。如何使用過濾器處理REST服務? servlet的?如果過濾器,它可能會在shiro過濾器之前被調用,這將導致它無法正常工作。 – teacurran