问题描述
我的 components.xml 中有这个配置:
I have this config in my components.xml:
<web:authentication-filter url-pattern="/resource/rest/*" auth-type="basic"/>
<security:identity authenticate-method="#{basicAuthenticator.login}"/>
嗯,我的 basicAuthenticator 是一个无状态接缝组件,我有一个登录方法,它根据凭据返回真/假.
Well, my basicAuthenticator is a Stateless seam component where i have that login method which returns true/false depending on credentials.
我真的很想找到请求的主机(网址).
I do really want to find the host (url adress) of the request.
当然我可以使用 ExternalContext 像:
Of course i can use ExternalContext like:
@In(value = "#{facesContext.externalContext}", required = false)
private ExternalContext externalContext;
但它给了我 null 因为我这里没有 jsf...
but it gives me null because i have no jsf here...
你知道其他方法吗?
谢谢.
推荐答案
Cristian,
因为 ServletFilter 总是在调用之前 FacesServlet,你总是会得到 null.
Because ServletFilter will always be called before FacesServlet, you will always get null.
所以不要使用
private @In FacesContext facesContext;
不再使用 Servlet 过滤器.
anymore when using Servlet Filter.
解决方案:好吧,它不可能是最好的解决方案,但它可以解决您想做的事情
Solution: well, it can not be The best solution but it solves what you want to do
创建一个 CustomAuthenticationFilter 如下
Create a CustomAuthenticationFilter as follows
@Scope(APPLICATION)
@Name("org.jboss.seam.web.authenticationFilter")
@Install(value = false, precedence = BUILT_IN)
@BypassInterceptors
@Filter(within = "org.jboss.seam.web.exceptionFilter")
public class CustomAuthenticationFilter extends org.jboss.seam.web.AbstractFilter {
/**
* Because of some private methods defined in AuthenticationFilter
* do Ctrl + C / Ctrl + V All of source code of AuthenticationFilter
*
* Except authenticate method which is shown bellow
*/
private void authenticate(HttpServletRequest request, final String username) throws ServletException, IOException {
new ContextualHttpServletRequest(request) {
@Override
public void process() throws ServletException, IOException, LoginException {
Identity identity = Identity.instance();
identity.getCredentials().setUsername(username);
try {
identity.preAuthenticate();
/**
* Yes, THE SAME LOGIC performed by authenticate-method must goes here
*/
/**
* Do not use @In-jection here
*
* Use context lookup instead
* For instance, UserService userService = (UserService) Contexts.lookupInStatefulContexts("userService");
*/
identity.postAuthenticate();
} finally {
// Set password to null whether authentication is successful or not
identity.getCredentials.setPassword(null);
}
}
}.run();
}
}
现在覆盖/WEB-INF/componets.xml 中的默认 AuthenticationFilter
<web:rewrite-filter view-mapping="/resource/rest/*"/>
<component name="org.jboss.seam.web.authenticationFilter" class="br.com.ar.seam.CustomAuthenticationFilter">
<property name="urlPattern">/resource/rest/*</property>
<property name="authType">basic</property>
</component>
并且要启用restURL,请执行以下操作
And To enable restURL do as follows
web.xml
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--HERE GOES NON-REST INTERCEPTED URL-->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.seam</url-pattern>
</servlet-mapping>
<!--HERE GOES REST INTERCEPTED URL-->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
现在,假设您要调用与 restURL servlet-mapping 匹配的 /resource/rest/user.在/WEB-INF/pages.xml 中声明
Now, let's suppose you want to call /resource/rest/user which matchs restURL servlet-mapping. In /WEB-INF/pages.xml declare
<page view-id="<VIEW_ID_GOES_HERE>">
<rewrite pattern="/resource/rest/user"/>
<rewrite pattern="/resource/rest/{userId}"/>
<!--userId comes from pattern shown above-->
<param name="userId" value="#{userService.userId}"/>
</page>
为避免 FacesServlet 拦截任何客户端资源,如 css、javaScript 和图像文件,您可以定义
To avoid FacesServlet intercept any client-side resource such as css, javaScript and images files, you can define
<servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/resource/*</url-pattern>
</servlet-mapping>
哪个不适用 JSF 生命周期.确保将 Seam Resource Servlet 放在 FacesServlet 声明之上.
Which does not apply JSF lifecycle. Make sure put Seam Resource Servlet above FacesServlet declaration.
这篇关于SEAM - 获取 base65 身份验证的 URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!