Широ - перенаправление на страницу входа после тайм-аута сессии - PullRequest
0 голосов
/ 14 мая 2018

Мне нужно перенаправить мое веб-приложение (Java + angular) на страницу входа, когда время сеанса истекло.Shiro выполняет перенаправление автоматически или это обрабатывается кодом?

Я пробовал несколько хаков, но у меня не получилось.Я попытался добавить тайм-аут сеанса в мой web.xml, но он просто не повлиял.Я попытался обновить свой shiro.ini, но потом не смог войти в свое приложение!

Не могли бы вы помочь найти ошибки в этих файлах или дать совет, что можно сделать в таком случае.

Заранее спасибо.

web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>ResourceManager</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- session-config>
    <session-timeout>1</session-timeout>
  </session-config>

  <error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/Login.html</location>
  </error-page-->
  
  <listener>
    <listener-class>
    	com.<our customized package>.logging.AppLifeCircleListener
    	</listener-class>
  </listener>
  <listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
  </listener>
  <filter>
    <filter-name>shiro-filter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>shiro-filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>
  <servlet>
    <servlet-name>login</servlet-name>
    <jsp-file>/Login.jsp</jsp-file>
  </servlet>
  <servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>
  			org.springframework.web.servlet.DispatcherServlet
 		</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/rest-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/management/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/privilege/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/file-explorer/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>login</servlet-name>
    <url-pattern>/Login.html</url-pattern>
  </servlet-mapping>
</web-app>

shiro.ini:

[main]

# LDAP Settinng
contextFactory = com.ibm.datafabrication.web.server.security.JndiLdapContextFactoryExt
contextFactory.url = ldap://<host>:389
contextFactory.systemUsername = <...>
contextFactory.keyPath = <>
contextFactory.encodedSystemPassword = ...

ldapRealm = com.<>.ActiveDirectoryRealm
ldapRealm.ldapContextFactory = $contextFactory
ldapRealm.userSearchFilter = (sAMAccountName={0})
ldapRealm.groupNameAttribute = cn
ldapRealm.searchBase = DC=<...>,DC=<...>,DC=com
ldapRealm.groupRolesMap = dfp_users:user,dfp_admins:admin

# SQLite Setting
ds = org.sqlite.SQLiteDataSource
ds.url = jdbc:sqlite:<>.db
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource = $ds
jdbcRealm.permissionsLookupEnabled = false
jdbcRealm.authenticationQuery = SELECT Password FROM Users WHERE Name=?
jdbcRealm.userRolesQuery = WITH uname(name) AS (VALUES(?)) SELECT 'user' FROM Users, uname WHERE Users.Name=uname.name UNION ALL SELECT 'admin' FROM (SELECT Id FROM Users, uname WHERE Users.Name=uname.name) LEFT JOIN Admins on Id = Admins.UserId WHERE UserId NOT NULL
credentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
credentialsMatcher.storedCredentialsHexEncoded = true
jdbcRealm.credentialsMatcher = $credentialsMatcher

authc.loginUrl = /Login.html
securityManager.realms = $jdbcRealm

authcStrategy = org.apache.shiro.authc.pam.FirstSuccessfulStrategy
securityManager.authenticator.authenticationStrategy = $authcStrategy

>>>>>>>>>>>>>>>>>>>>> What I tired

# session timeout
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionMode=native
securityManager.sessionManager.globalSessionTimeout = 60000
securityManager.sessionManager = $sessionManager

sessionValidationScheduler = org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler
sessionValidationScheduler.interval = 30000
securityManager.sessionManager.sessionValidationScheduler = $sessionValidationScheduler

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

[urls]
/logout = logout
/css/** = anon
/images/** = anon
/plugins/** = anon
/favicon.ico = anon
/tdf.ico = anon
/Login.html = authc
...
/** = authc, roles[user]

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

В конце я реализовал решение для тайм-аута на стороне клиента, используя пакет @ ng-idle / core angular:

https://www.npmjs.com/package/@ng-idle/core

https://hackedbychinese.github.io/ng2-idle/

Я также использовал @ ng-idle / keepalive для непрерывной проверки связи с сервером и поддержания его в рабочем состоянии:

handleIdle(){
  // sets an idle timeout of x seconds, for testing purposes.
 this.idle.setIdle(/*Config.SESSION_IDLE*/ this.sessionIdle);
 // sets a timeout period of y seconds. after x+y seconds of inactivity, the user will be considered timed out.
 this.idle.setTimeout(/*Config.SESSION_TIMEOUT*/ this.sessionTimeout);
 // sets the default interrupts, in this case, things like clicks, scrolls, touches to the document
 this.idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);

 this.idle.onIdleEnd.subscribe(() => this.idleState = 'No longer idle.');
 this.idle.onTimeout.subscribe(() => {
   this.idleState = 'Timed out!';
   this.timedOut = true;
 });
 this.idle.onIdleStart.subscribe(() => {
         this.idleState = 'You\'ve gone idle!'
         this.idleModal.open();
     }    
 );
 this.idle.onTimeoutWarning.subscribe((countdown) => {
     this.idleState = 'You\'ve gone idle! Your session will be timed out in ' + countdown + ' seconds!';

     if (countdown == 1){
         window.location.href = "../logout";
     }
 });

 // sets the ping interval to z seconds
 this.keepalive.interval(/*Config.KEEP_ALIVE_INTERVAL*/this.keepAliveInterval);

 this.keepalive.onPing.subscribe(() => {
     this.lastPing = new Date();
     this.resourcesService.ping();
 });

 this.reset(); }
0 голосов
/ 15 мая 2018

Вы можете оставить свой web.xml как есть, поскольку Широ не имеет ничего общего с конфигурацией в этом файле. Существует разница в HttpSession, используемом HttpServletRequest вашего сервлета и Shiro Session. Это совершенно разные вещи. Так что не смущайтесь конфигурацией сеанса сервлетом и Сиро. В этом случае мы разрешим Широ обработать вашу сессию.

Проблемы с вашим shiro.ini
Вы переопределяете параметры, которые пишете в DefaultWebSessionManager:

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager // Define a sessionManager variable
securityManager.sessionMode=native
securityManager.sessionManager.globalSessionTimeout = 60000 // set a securityManager.sessionManager property
securityManager.sessionManager = $sessionManager // override the property by setting the object

Сначала вы должны установить объект:

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
securityManager.sessionMode=native
securityManager.sessionManager.globalSessionTimeout = 60000

Вам не нужен ExecutorServiceSessionValidationScheduler, так как valdiator уже предоставлен DefaultWebSessionManager. Рабочий пример может выглядеть следующим образом:

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
# Session timeout token_ttl_ms = 14 days
sessionManager.globalSessionTimeout = 1209600000
# Session valdiation = 15 minutes
sessionManager.sessionValidationInterval = 900000

securityManager = org.apache.shiro.web.mgt.DefaultWebSecurityManager
securityManager.sessionManager = $sessionManager

DefaultWebSessionManager

DefaultWebSessionManager предоставляет все функции, которые вы ищете из коробки (в основном). Когда сеанс истекает, DefaultWebSessionManager вызывает onExpiration на своем super , который уведомляет всех своих слушателей об истечении срока действия SessionManager . Вы можете просто зарегистрировать SessionListener в своем SessionManager и запустить перезагрузку или перенаправление по его onExpiration методу. Может быть, этот подход достаточно подходит для приложений jsp / jspx.
В любом случае, прочитайте, как зарегистрировать слушатель сеанса здесь в официальных документах.

Альтернативный подход

Другой подход может заключаться в том, чтобы ваш клиент управлял состоянием сеанса и позволял ему постоянно проверять срок действия, вызывая вашу службу. Это может быть сделано таймером или циклом в JavaScript.

Примечание

org.apache.shiro.authc.credential.Sha256CredentialsMatcher устарело с 2010 года.
Используйте HashedCredentialsMatcher напрямую и установите его свойство hashAlgorithmName.

...