如何在web.xml中配置Ember.js路由以实现JAAS表单认证?
问题分析与解决方案
核心问题
你用了Ember的hash模式(URL带#),浏览器会把#后面的路由部分(比如#/admin)保留在本地,不会发送给Tomcat服务器。所以你web.xml里配置的<url-pattern>/admin</url-pattern>根本不会被触发——服务器收到的请求始终是/test_auth/,看不到#/admin,自然不会启动JAAS认证流程。
解决方案
有两种可行方案,根据你的需求选择:
方案1:切换到Ember的History模式(推荐)
这种模式下URL不带#,服务器能完整接收路由路径,Tomcat的安全约束可以直接生效。
- 修改Ember配置:在
environment.js中把locationType改成'history':// config/environment.js module.exports = function(environment) { let ENV = { // ...其他配置 locationType: 'history', // ... }; return ENV; }; - Tomcat配置调整:
- 确保web.xml中添加欢迎页面,指向Ember的入口文件:
<welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> - 为了避免刷新页面时404,需要在Tomcat中配置
RewriteValve(Tomcat 8.5+支持):
在conf/server.xml的<Host>标签内添加:
然后在项目的<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />WEB-INF下创建rewrite.config文件,内容:RewriteCond %{REQUEST_PATH} !-f RewriteRule ^/(.*)$ /index.html [L]
- 确保web.xml中添加欢迎页面,指向Ember的入口文件:
- 修正web.xml的安全约束:
现在URL是http://localhost:8085/test_auth/admin,直接用原来的配置即可:
此时访问<security-constraint> <web-resource-collection> <web-resource-name>admin</web-resource-name> <url-pattern>/admin</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint>/admin会触发Tomcat的FORM认证,未登录时自动跳转到你配置的/login页面。
方案2:保留Hash模式,前端路由守卫+后端认证接口
如果必须用hash模式,需要通过前端主动触发后端的认证检查:
- 后端添加认证检查接口:
写一个简单的Servlet(比如CheckAuthServlet),映射路径为/api/check-auth,不需要复杂逻辑,只需返回200状态码即可——Tomcat的安全约束会帮你拦截未认证请求。 - web.xml添加接口的安全约束:
<security-constraint> <web-resource-collection> <web-resource-name>auth-check</web-resource-name> <url-pattern>/api/check-auth</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint> - 前端路由添加守卫:
在Ember的admin路由中,进入前调用后端的认证接口,触发认证流程:
当用户访问// app/routes/admin.js import Route from '@ember/routing/route'; export default class AdminRoute extends Route { async beforeModel(transition) { try { // 发送请求到受保护的接口,带上Cookie确保会话有效 await fetch('/api/check-auth', { credentials: 'include' }); } catch (error) { // 未认证,跳转前端登录路由(或等待后端FORM认证跳转) this.transitionTo('login'); transition.abort(); } } }#/admin时,前端会主动调用/api/check-auth,这个请求会被Tomcat的安全约束拦截,跳转到登录页面。
额外注意事项
- 你的FORM登录页面
/login和错误页面/error-login,如果是Ember路由,需要确保Tomcat能返回Ember的index.html,让前端路由处理这些路径。 - 确认Tomcat的JAAS Realm配置正确(你提到其他认证功能正常,这部分应该没问题)。
内容的提问来源于stack exchange,提问作者bubbly
相关产品推荐
相关产品推荐

