Really big problems. Homework assignment again. I've pretty much given up on trying to get it to work, there isn't enough time anymore for it. I've tried reading through everything on security on docs.oracle, everything on security on NetBeans, everything provided with the class (textbook doesn't cover any of this, so can't blame it on an outdated book this time) and a bunch of tutorials through google and alot of questions on here. I can't get it to work.
I'm not looking for an answer to the homework, more of what I need to look at and things to double-check that I might be overlooking....
The application should allow users in two different groups to login. Admin users have access to everything while User users have access to only /user/*. We aren't restricted to strictly programmatic security and we aren't restricted to a specific declarative security. We have to create a servlet to control page flow (as much as I mentioned it to the instructor that JSF comes with a controller and page flow can be controlled through the framework already didn't affect his decision any.) If someone not currently logged in tries to access one of the protected areas, they should be prompted to login/redirected to the login page/whatever needs to happen to login based on our security implementation. If a logged in User user tries to access the admin area, they should prompted they aren't Admin, no details on if they should just be returned to where they were, logged out or prompted to login as an Admin. The only requirement is we can't use a database to store usernames and passwords.
So I went with setting up two users in the file realm, one as User, one as Admin. I tried setting it up for basic authentication, it doesn't prompt for login when the user runs the page. I tried creating a custom login/login error pages and form authentication, it wouldn't display my login form when the user ran the page. So far, the only thing I've been able to do is have the Login page as the welcome file and call the servlet on form submission and it uses request.login(username, password) and logs the user in if they are found in the realm and everything matches. I can then check the role and set things in the user's bean and forward them to the proper start page based on the assigned role. But if I run it and navigate to another page without entering data into the form and submitting it to login, the pages display. If I login as the User role and navigate to one of the admin area pages, it lets me. I've set up security constraints for the urls, I've used filters from examples I've seen on here for the different urls, and they don't get called.
There is probably something simple I am missing, and coming into this class not knowing html and stuff other than java is probably the biggest problem, and I honestly don't know how I'm borderline A in this class....
There is more to the project than this, but the rest isn't something I see myself having a problem with, but I've been hung up on the security part of this for most of the week and haven't even started on it.
web.xml
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Controller</servlet-name>
<servlet-class>Project2.Controller</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Controller</servlet-name>
<url-pattern>/Controller</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>AdminConstraint</display-name>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<description/>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>Admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>UserConstraint</display-name>
<web-resource-collection>
<web-resource-name>user</web-resource-name>
<description/>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>User</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<description/>
<role-name>User</role-name>
</security-role>
<security-role>
<description/>
<role-name>Admin</role-name>
</security-role>
</web-app>
login.xhtml
<f:view>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>JSP Page</title>
</head>
<body>
<h1><h:outputText value="Welcome! Choose an action below."/></h1>
<form method="Post" action="Controller">
<h:inputText id="userName" value=""/>
<h:inputSecret id="password" value=""/>
<h:commandButton value="Login" type="submit"/>
</form>
</body>
</html>
</f:view>
So based on what you have your goal seems to achieve container based authentication and authorization. So in addition to what you have you also need to add login configuration to your Deployment Descriptor like this:
<login-config>
<auth-method>FORM</auth-method>
<realm-name>yourRealmName</realm-name>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/error.xhtml</form-error-page>
</form-login-config>
</login-config>
The above configuration specifies the login page where the user types in the username and password and the error page to which it is redirected if the authentication fails.
And in your login.xhtml you need to specify to POST the form to j_security_check like this:
<form action="j_security_check" method="POST">
<input type="text" name="j_username" />
<input type="secret" name="j_password" />
...
</form>
Alternatively to container based authentication, you can also do programmatic authentication where upon submitting the form. The user role is checked and the desired action outcome is returned. I think you don't need that controller anymore.
More details on this see the Java EE 6 documentation here
Related
I have created a filter login
How to redirect a logged out user to the home page in Java EE/JSF?
But now I want to set just some specific pages have to login. I created some pages and put them into private folder, and changed the filter's url like this
<filter-name>AuthenticationLogin</filter-name>
<filter-class>filter.AuthenticationLogin</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationLogin</filter-name>
<url-pattern>/private/*</url-pattern>
</filter-mapping>
It doesn't work :(
Any suggestion. Thanks in advance.
Your filter mapping is correct. You can use following redirection
response.sendRedirect(request.getContextPath() + "/login.jsf");
in filter.
I have one application running on tomcat sever.I removed the path in in server.xml so i am able to access the application like
http://localhost:8080/login.xhtml
I am using Pretty faces as well for URL rewrite.
Now i want to know how to send a request to server like
http://localhost:8080
so that it should display my login page.
My pretty-config.xml is
<url-mapping id="login">
<pattern value="/" />
<view-id value="/login.xhtml" />
</url-mapping>
it is not working.please let me know the solution.
Your pretty-config part (which is valid) tells that a path / should be mapped to /login.xhtml and may be referred to as pretty:login in outcomes of JSF components (as well as in action methods).
From here there are two possible options for inconsistencies:
Prettyfaces must be pointed to a valid URL, meaning that FacesServlet mapping in web.xml should be *.xhtml in your case, not faces/*, not *.jsf, etc.
Prettyfaces should be used appropriately in your JSF components. For instance, <h:link outcome="pretty:login" value="Home" /> will render an HTML a element with the value / (which will internally show login.xhtml when you click on it).
Also, it would be helpful to read the excellent PrettyFaces documentation.
I'm using a #ConverstationScoped bean, I want to create a nice error page for the case you change the cid parameter manually.
<error-page>
<exception-type>javax.enterprise.context.NonexistentConversationException</exception-type>
<location>/nonExistentConversation.xhtml</location>
</error-page>
<error-page>
<exception-type>org.jboss.weld.context.NonexistentConversationException</exception-type>
<location>/nonExistentConversation.xhtml</location>
</error-page>
The problem is that the cid parameter is passed to the error pages, and these error pages are also failing because they can't find the conversation, which brings them to the default exception page.
What is the best solution for this problem? Creating a filter, custom handlers, others?
Atm I'm using a non jsf page for my conversation error page.
I've got this in my web.xml:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
so a page named error.html won't go trough the Faces Servlet and the error page will be displayed iso searching a conversation with the cid in the request parameter.
The disadvantage is that you can't do any JSF stuff in them (i18n, stack traces in dev, ..)
Is it possible to integrate Spring Security 3 and JSF 2, keeping JSF working as default, instead of show the new url when the user navigates, keep the old url, without using the redirect JSF attribute to navigate through pages?
I can't found documentation about this. All articles I found the author redirect the page when navigate.
Thanks
By default the FilterSecurityInterceptor will only execute once-per-request and doesn't do security re-checking unless there is change in the url but with JSP/JSF forwards the page is rendered as a response to the current request and the url in the browser contains the address of the previous page. So for this just set once-per-request attribute to false in your http element in applicationContext thus forcing security rechecking.
<http auto-config="true" use-expressions="true" once-per-request="false">
and add a dispatcher for forwards in springSecurityFilterChain filter-mapping in your web.xml
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
More info
Alternatively, you can also enable page redirection by appending the parameter faces-redirect=true to the outcome like this:
<h:form>
<h:commandButton action="page1?faces-redirect=true" value="Page1" />
</h:form>
But do also remember that in your case GET request looks more appropriate and as BalusC says its not good practice to use POST for bookmarkable page-to-page navigation.
So do GET using <h:link> or <h:button>or faces-redirect=true also causes a GET request.
Also see:
when-should-i-use-houtputlink-instead-of-hcommandlink
Post-Redirect-Get
pattern
In my struts2 based application i need to include working template (a jsp file).I have designed the layout and has everything in place.only part of application which will change throughout the application is working area.
On my index.jsp file i need to include menu which are database driven and for which i need to hit the action one way which is coming to my mind is like using
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=welcome.action">
in the head section of my index.jsp,but i don't want to have redirect at first place in my application.
is there any other way to achieve this?
That's a normal approach; nothing wrong with it.
Another is to define an action as a welcome page, but you'll need to define dispatcher elements on the filter as per this SO answer.
create an empty file name welcome in your web-content folder.Add follwinf entry to your web.xml
<filter>
<filter-name>action2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>action2</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
replace your welcome list file in web.xml as
<welcome-file-list>
<welcome-file>welcome</welcome-file>
</welcome-file-list>
and finally in your strus.xml do something like
<action name="welcome" class="welcome.action">
<result>/index.jsp</result>
</action>
what we are trying to do is that when we hit example.com instead of showing the welcome jsp file we are hitting the action and using its result.In this case your URL will remain same say www.mysite.com