Reputation: 1112
When I am using jsf with spring boot there is no problem to access the jsf bean, but when I add spring security I get access denied 403 when trying to access pages using jsf bean function, I can only access the pages with the url. I've been searching a lot to solve this issue but nothing did work, please if someone can help me solve this issue.
here is my code:
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";
}
}
config file of 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");
}
}
snippet code from the view
<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>
Upvotes: 1
Views: 719
Reputation: 1112
I was missing this line in the form:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
Upvotes: 0
Reputation: 12337
Let me start by addressing all of your comment from 2020-06-05 13:41:36Z above:
... if i take off "@ManagedBean" it won't be a bean
Wrong, something 'being' a (java)bean or not has nothing to do with annotations. What it takes for a plain java class to become a javabean can be read here:
When a java bean becomes a real managed bean, managed by A container (Spring, JSF, CDI, EJB, ...) is a different ballgame
and it cannot return a view.
Wrong again, something, in the jsf sense, being able to 'return a view' or not is dependent on the managed bean (Spring, JSF, CDI, ...) being accessed from a JSF 'page'returning a String or not AND as long as the managed bean is available in the EL resolvers used by facelets/jsf
Actually a JSF component on a facelets page is the better description
and if i take of "@Autowired" i cannot use injection right.
Wrong again... @Autowired
is the old spring annotation for 'injecting' other managed beans. Other bean managers/containers have the same features.
JSF has (or rather had) @ManagedProperty
(long deprecated in comination with its @ManageBean
in favour of CDI managed beans), CDI has @Inject
with @Named
which spring now also supports as an alias to @Autowired
and @Component/@Controller
The last part of your comment
I want to add access to jsf bean if spring security config but i don't know how ?
Wrong again, you access a facelets/jsf page and you (may) control access to it via spring security (or other more independent ways like JBoss/RedHat KeyCloak or Apache Shiro or the standardized javaee-8 security api
So why is this not an answer to your question (but I'll leave it here anyway). In your question you state
I cannot access pages using bean, I can only access the pages with the url.
Then debug this... Set breakpoints, are there redirects, any errors, how does the url look like when you type it in, how does it look like when returned from method call to a bean, with and without spring security. Those are relevant details. Make a real 'https://stackoverflow.com/help/minimal-reproducible-example'
And lastly
I've been searching a lot to solve this issue but nothing did work,
How to ask states to search and keep track and unfortunately it only implies to mention in the question what you found (if you don't mention it, it cannot help the ones who try to help you in narrowing things down). and 'nothing did work' is not the best description. Did you get 404's? 500's?
Upvotes: 3