使用spring security时无法访问jsf页面,出现403

Posted

技术标签:

【中文标题】使用spring security时无法访问jsf页面,出现403【英文标题】:Cannot access jsf page when using spring security, 403 occurs 【发布时间】:2020-09-24 04:54:35 【问题描述】:

当我在 spring boot 中使用 jsf 时,访问 jsf bean 没有问题,但是当我添加 spring security 时,当我尝试使用 jsf bean 功能访问页面时,我得到 access denied 403,我只能访问带有网址。 我一直在寻找很多来解决这个问题,但没有任何工作,请如果有人可以帮助我解决这个问题。

这是我的代码:

jsf BeanProduit.java

@ManagedBean
@Component
@SessionScoped
public class BeanProduit 

    @Autowired
    @Qualifier("produitsPrixServiceImpl")
    private CrudService<ProduitsPrix> produitsPrixService;

    @Autowired
    @Qualifier("produitsStockServiceImpl")
    private CrudService<ProduitsStock> produitsStockService;

    private List<ProduitsStock> produits;
    private Logger logger = Logger.getLogger(getClass().getName());

    public BeanProduit() 
        produits = new ArrayList<ProduitsStock>();
    

    @PostConstruct
    public void init() 
        produits = getListProductsFinal();
    

    public String loadProduct(int codePdt) 
        logger.info("loading product: " + codePdt);
        try 
            // get product from database
            ProduitsPrix product = produitsPrixService.findById(codePdt);
            // put in the request attribute ... so we can use it on the form page
            ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
            Map<String, Object> requestMap = externalContext.getRequestMap();
            requestMap.put("product", product);
         catch (Exception exc) 
            // send this to server logs
            logger.log(Level.SEVERE, "Error loading product id:" + codePdt, exc);
            // add error message for JSF page
            addErrorMessage(exc);
            return null;
        
        return "/pages/form-validation";
    


spring security DemoSecurityConfig.java的配置文件

@EnableWebSecurity
public class DemoSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private DataSource securityDataSource;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.jdbcAuthentication().dataSource(securityDataSource);
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.authorizeRequests()
            .antMatchers("/assets/**")
            .permitAll()
            .antMatchers("/authentication/login.xhtml?logout").hasAnyRole("EMPLOYEE")
            .antMatchers("/**").hasRole("ADMIN")
            .and().formLogin().loginPage("/authentication/login.xhtml")
            .loginProcessingUrl("/authenticateTheUser").permitAll()
            .defaultSuccessUrl("/", true)
            .and().logout().permitAll()
            .and().exceptionHandling().accessDeniedPage("/error/error-403.xhtml");
    


sn-p 代码视图

<h:form>
<ui:repeat value="#beanProduit.produits" var="produit">
    <tr>
        <td>#produit.codePdt</td>
        <td>#produit.nomPdt</td>
        <td>#produit.prixPdt</td>
        <td>#produit.qtePdt</td>
        <td class="text-center">
            <h:commandButton class="btn btn-primary" value="Acheter" action="#beanProduit.loadProduct(produit.codePdt)" />
        </td>
    </tr>
</ui:repeat>
</h:form>

【问题讨论】:

你是从哪里学会在课堂上同时使用@ManagedBean@Component 的?选择一个和正确的对应范围。 ;正在寻找bthev@Autowired你应该使用v@Component 在 Spring Security 中如何以及在何处访问 jsf bean 或者你不能访问页面本身?有什么错误吗? @Kukeltje 如果我取消“@ManagedBean”,它将不是一个 bean,也无法返回视图。如果我选择“@Autowired”,我就不能正确使用注入。如果 spring 安全配置,我想添加对 jsf bean 的访问,但我不知道如何? 离题。无论我的“未回答”中的内容如何,​​您的架构实际上都很好。很多“初学者”做这个waaaaaay更错误。赞美。你这样做就像***.com/questions/30639785/… 【参考方案1】:

首先让我从上面的2020-06-05 13:41:36Z 解决您的所有评论:

...如果我去掉“@ManagedBean”,它就不是豆子了

错了,“成为”(java)bean 与注释无关。一个普通的 java 类变成一个 javabean 需要什么可以在这里阅读:

What is a JavaBean exactly?

当一个java bean变成真正的托管bean,由A容器(Spring、JSF、CDI、EJB、... ) 是不同的球赛

What is difference between JavaBean and ManagedBean

它不能返回视图。

又错了,在 jsf 的意义上,是否能够“返回视图”取决于从 JSF 的“页面”访问的托管 bean(Spring、JSF、CDI、...)返回一个字符串与否 AND 只要托管 bean 在 facelets/jsf 使用的 EL 解析器中可用

Navigating to another page JSF

实际上,facelets 页面上的 JSF 组件是更好的描述

What is the difference between JSF and Facelets? What is the difference between JSF, Servlet and JSP?

如果我使用“@Autowired”,我将无法正确使用注入。

又错了...@Autowired 是用于“注入”其他托管 bean 的旧 spring 注释。其他 bean 管理器/容器具有相同的功能。

JSF 有(或者更确切地说有)@ManagedProperty(与其@ManageBean 一起被长期弃用,以支持 CDI 托管 bean),CDI 有@Inject@Named,spring 现在也支持作为 @ 的别名987654340@和@Component/@Controller

What is the difference between @Inject and @Autowired in Spring Framework? Which one to use under what condition? Both @Component and @Named for the same bean class


实际上您对评论的误解都在

中得到解决 Spring JSF integration: how to inject a Spring component/service in JSF managed bean?

评论的最后部分

如果 spring 安全配置,我想添加对 jsf bean 的访问,但我不知道如何?

又错了,您访问 facelets/jsf 页面,并且(可能)通过 Spring Security(或其他更独立的方式,如 JBoss/RedHat KeyCloak 或 Apache Shiro 或 standardized javaee-8 security api )控制对它的访问

那么为什么这不是您问题的答案(但无论如何我都会把它留在这里)。在你的问题中你说

我无法使用 bean 访问页面,我只能访问带有 url 的页面。

然后调试这个...设置断点,是否有重定向,是否有任何错误,输入时 url 的样子,从方法调用返回到 bean 时的样子,有和没有 spring security .这些是相关的细节。做一个真正的'https://***.com/help/minimal-reproducible-example'

最后

我一直在寻找解决这个问题的方法,但没有任何效果,

How to ask 声明要搜索和跟踪,不幸的是,它仅暗示在问题中提及您发现的内容(如果您不提及,它无法帮助那些试图提供帮助的人你在缩小范围)。而“没有任何效果”并不是最好的描述。你有404的吗? 500的?

【讨论】:

非常感谢您向我解释这一点,我仍然是 java 的初学者,春天这就是为什么我很难过。实际上,我在尝试访问页面时遇到了拒绝访问 403。 那你为什么不提这个非常非常相关的403呢?比较正常请求和失败请求的 url。调试,设置断点...请使用现代 JSF(JSF 2.3,没有 @ManagedBean,使用 Spring 或 CDI,但始终使用 @Named@Inject 使其可移植。学习一个很好的教程。【参考方案2】:

我在表格中遗漏了这一行:

<input type="hidden" name="$_csrf.parameterName" value="$_csrf.token"/>

【讨论】:

以上是关于使用spring security时无法访问jsf页面,出现403的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 上的 Spring Security/JSF/Hibernate 意外会话劫持?

新的 Spring Security 登录会话启动时是不是启动了新的 JSF 会话?

我们可以集成 JSF 2.0 + Spring 4.2.X + Spring Security 4.2.X [重复]

Spring-security - 无法访问 ServletException

如何在 JSF 中使用 Spring Security Facelets 标签库

spring security 使用hibernate和jsf认证不同的配置文件和权限