W jaki sposób można ograniczyć dostęp do stron tylko dla zalogowanych użytkowników?

0

Witam

W jaki sposób można ograniczyć dostęp do stron tylko dla zalogowanych użytkowników?
Aplikacja JSF + Hibernate, dane (login i hasło zapisane w bazie danych), pobierane przez metodę i zapisane w ArrayList, następnie porównane z danymi wpisywanymi na stronie logowania.

Struktura katalogu:

Web Pages/zalogowani/zalogowany.xhtml
Web Pages/index.xhtml
Web Pages/niezalogowani.xhtml

Pozdrawiam

1

Nie wiem, co tam JSF ma swojego do autentykacji / autoryzacji, ale zwykle rozwiązuje się to tak, że rejestrujesz nowy filtr w web.xml do jakiejś częsci serwisu (/zalolgowani/*), który sprawdza np. na podstawie sesji, czy gościu ma uprawnienia, czy nie, a jeśli nie, to przekierowuje do strony logowania. Spring Security działa w ten sposób i jest bardzo mało inwazyjne (możesz używać z czym tam chcesz, np. z JSF).

http://static.springsource.org/spring-security/site/

0
vall75 napisał(a):

Witam

W jaki sposób można ograniczyć dostęp do stron tylko dla zalogowanych użytkowników?
Aplikacja JSF + Hibernate, dane (login i hasło zapisane w bazie danych), pobierane przez metodę i zapisane w ArrayList, następnie porównane z danymi wpisywanymi na stronie logowania.

Struktura katalogu:

Web Pages/zalogowani/zalogowany.xhtml
Web Pages/index.xhtml
Web Pages/niezalogowani.xhtml

Pozdrawiam

W web.xml zdefiniuj sobie role i które zasoby są zabezpieczone:

<security-constraint>
        <web-resource-collection>
            <web-resource-name>All resources</web-resource-name>
            <description>Protects all resources</description>
            <url-pattern>/views/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>ROLA_DLA_ZABEZPIECZONYCH_ZASOBOW</role-name>
        </auth-constraint>
    </security-constraint>

    <security-role>
        <role-name>ROLA_DLA_ZABEZPIECZONYCH_ZASOBOW</role-name>
    </security-role>

Do tego aplikacja musi zapewniać logowanie, może być prosty login form.
No i sesja http musi zawierać wspomnianą rolę, tak więc jakikolwiek wybierzesz komponent autentykacyjny musi on nadać sesji odpowiednią rolę.

Druga opcja to tak jak wspomniano filtr na zasoby, też w web.xml:

<filter>
        <filter-name>SecurityFilter</filter-name>
        <filter-class>pl.test.MySecurityFilter</filter-class>
        <init-param>
            <param-name>securedPage</param-name>
            <param-value>/zalogowani/zalogowany.xhtml</param-value>
        </init-param>
    </filter>

W implemetacji filtra (rozszerzasz javax.servlet.Filter) zrobisz co tam sobie uważasz:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	
        if (isUserAuthorised()) {
            chain.doFilter(request, response);
        } else {
            goToLoginPage(response);
        }
    }

Oczywiście możesz łączyć obie opcje wedle potrzeb.

0

Witam

W dalszym ciągu można wejść na stronę wpisując adres ręcznie:
"http://localhost:8080/Logowanie/faces/zalogowani/zalogowany.xhtml".

Próbowałem sklecić prosty projekt z Spring Security, ale póki co nic z tego nie wyszło.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <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-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
    <security-constraint>
        <display-name>Admin</display-name>
        <web-resource-collection>
            <web-resource-name>zalogowany.xhtml</web-resource-name>
            <description/>
            <url-pattern>/zalogowani/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <description/>
            <role-name>Admin</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>security</realm-name>
        <form-login-config>
            <form-login-page>/index.xhtml</form-login-page>
            <form-error-page>/index.xhtml</form-error-page>
        </form-login-config>
    </login-config>
    <security-role>
        <description/>
        <role-name>Admin</role-name>
    </security-role>
</web-app>

Funkcja użyta do logowania:

    public String Zaloguj(String login, String pass){
        String result = "Sukces";//Porazka
        boolean test = false;
        int licznik = 0;
        //pobieranie danych
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        listCredentials = session.createQuery("from Credentials").list();
        session.getTransaction().commit();
        
        while(test == false && listCredentials.size()>licznik){
            
            if(listCredentials.get(licznik).getLogin().equals(login)){
                
                test = true;
                result = "Sukces";
                    
                    if(listCredentials.get(licznik).getPass().equals(pass)){
                    
                        test = true;
                        result = "Sukces";
                        
                    }else{
                        
                        test = false;
                        result = "Porazka";
                        
                    }
            }else{
            
                test = false;
                result = "Porazka";
                
            }
            
            licznik ++;
        
        }

        return result;
    }

Czekam na pomysły.

Pozdrawiam

0
vall75 napisał(a):

Czekam na pomysły.

Pozdrawiam

Sesja http musi zawierać Subject po autentykacji.
Poczytaj np. o JAAS. Tu masz jeden z przykładów http://www.kopz.org/public/documents/tomcat/jaasintomcat.html

0

Witam

Znalazłem ciekawy tutorial

http://jugojava.blogspot.com/2011/02/jdbc-security-realm-with-glassfish-and.html

JAAS.
Próbowałem zastosować do testowej aplikacji, niestety nie można się wcale zalogować, tj. zawsze kieruje na stronę niezalogowani.xhtml.

Myślę, że może to być problem z którymś z plików:

  1. index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>JsfSecurityRealm1</title>
    </h:head>
    <h:body>
        JsfSecurityRealm1
        <form method="post" action="j_security_check">
            <h:panelGrid columns="2">
                <h:outputLabel for="j_username" value="Username" />
                <input type="text" name="j_username" />

                <h:outputLabel for="j_password" value="Password" />
                <input type="password" name="j_password" />

                <h:outputText value="" />
                <h:panelGrid columns="2">
                    <input type="submit" name="submit" value="Login" />
                    <h:button outcome="index" value="Cancel" />
                </h:panelGrid>
            </h:panelGrid>
        </form>

        <!--<h:form>
            <h:panelGrid>
                <h:inputText id="login" value="{credentials.login}"/>
                <h:inputSecret id="pass" value="{credentials.pass}"/>
            </h:panelGrid>
            <h:commandButton value="Zaloguj" action="{securityControler.Zaloguj(credentials.login, credentials.pass)}"/>
        </h:form>-->
    </h:body>
</html>
  1. faces-config.xml
<faces-config version="2.0"
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
    <managed-bean>
        <managed-bean-name>groups</managed-bean-name>
        <managed-bean-class>model.Groups</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <managed-bean-name>credentials</managed-bean-name>
        <managed-bean-class>model.Credentials</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <managed-bean-name>persons</managed-bean-name>
        <managed-bean-class>model.Persons</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <managed-bean-name>securityControler</managed-bean-name>
        <managed-bean-class>model.SecurityControler</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    <!--<navigation-rule>
        <from-view-id>/index.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>Porazka</from-outcome>
            <to-view-id>/niezalogowany.xhtml</to-view-id>
        </navigation-case>
        <navigation-case>
            <from-outcome>Sukces</from-outcome>
            <to-view-id>/zalogowani/zalogowany.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>-->
    <managed-bean>
        <managed-bean-name>authBackingBean</managed-bean-name>
        <managed-bean-class>model.AuthBackingBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
</faces-config>
  1. AuthBackingBean.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package model;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;


public class AuthBackingBean {

    /** Creates a new instance of AuthBackingBean */
    public AuthBackingBean() {
    }

    private static Logger log = Logger.getLogger(AuthBackingBean.class.getName());

    public String logout(){
        String result="index?faces-redirect=true";

        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
        try{
            request.logout();
        } catch(ServletException e){
            log.log(Level.SEVERE,"Failed to logout user!", e);
            result ="/loginError?faces-redirect=true";
        }

        return result;
    }

}
  1. web.xml
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	 version="3.0">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
        <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>jdbc_JsfSecurityRealm1-realm</realm-name>
        <form-login-config>
            <form-login-page>/faces/index.xhtml</form-login-page>
            <form-error-page>/faces/niezalogowany.xhtml</form-error-page>
        </form-login-config>
    </login-config>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Zalogowani</web-resource-name>
            <url-pattern>/faces/zalogowani/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>ADMINS</role-name>
            <role-name>USERS</role-name>
        </auth-constraint>
    </security-constraint>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>
  1. sun-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD GlassFish Application Server 3.0 Servlet 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd">
<sun-web-app error-url="">
    <context-root>/</context-root>
    <security-role-mapping>
    <role-name>ADMINS</role-name>
    <group-name>ADMINS</group-name>
  </security-role-mapping>
    <security-role-mapping>
    <role-name>USERS</role-name>
    <group-name>USERS</group-name>
  </security-role-mapping>
  <!--<context-root>/JsfSecurityRealm1</context-root>
  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>-->
</sun-web-app>

Hasła zapisane są w bazie przy użyciu szyfrowania MD5.
Konfiguracja połączenia do PostgrSql z poziomu glassfish-3.1.1 wygląda poprawnie, można ping'ować.

Próbowałem również odtworzyć projekt z pliku .war na bazie mysql.
Jeżeli wpiszę nieprawidłowe dane logowania to kieruje do katalogu /public/..., w przypadku wpisania prawidłowych danych kieruje do pliku index.xhtml.

Pozdrawiam

0

Witam

Działa, z tym, że trochę dziwnie, tj, po zalogowaniu nie kieruje na strony /admin/admins.xhtml, czy /users/users.xhtml.
Muszę wpisać adres w przeglądarkę, następnie kieruje mnie na stronę logowania w /public/login.xhtml i wtedy po zalogowaniu kieruje mnie dopiero na stronę /admins/admins.xhtml.
Po wylogowaniu jeżeli wpiszę dane usera to wyswietli się "HTTP Status 403 - Access to the requested resource has been denied" ponieważ będzie mnie kierowało na stronę /admins/admins.xhtm zamiast /users/users.xhtml.

sun-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD GlassFish Application Server 3.0 Servlet 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd">
<sun-web-app error-url="">
  <context-root>/JsfSecurityRealm2</context-root>

  <security-role-mapping>
		<role-name>ADMIN</role-name>
		<group-name>ADMIN</group-name>
  </security-role-mapping>
  <security-role-mapping>
		<role-name>USER</role-name>
		<group-name>USER</group-name>
  </security-role-mapping>

  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>
</sun-web-app>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <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-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>

  <context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>resources.application</param-value>
  </context-param>
  <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  </listener>
    <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>
    <login-config>
		<auth-method>FORM</auth-method>
		<realm-name>jdbc-realm</realm-name>
		<form-login-config>
			<form-login-page>/faces/public/login.xhtml</form-login-page>
			<form-error-page>/faces/public/loginError.xhtml</form-error-page>
		</form-login-config>
    </login-config>
    <security-constraint>
		<web-resource-collection>
			<web-resource-name>Admin user</web-resource-name>
			<url-pattern>/faces/admins/*</url-pattern>
			<http-method>GET</http-method>
      		<http-method>POST</http-method>
		</web-resource-collection>
		<auth-constraint>
			<role-name>ADMIN</role-name>
		</auth-constraint>
	</security-constraint>

	<security-constraint>
		<web-resource-collection>
			<web-resource-name>Admin user</web-resource-name>
			<url-pattern>/faces/users/*</url-pattern>
			<http-method>GET</http-method>
      		<http-method>POST</http-method>
		</web-resource-collection>
		<auth-constraint>
			<role-name>ADMIN</role-name>
			<role-name>USER</role-name>
		</auth-constraint>
	</security-constraint>

    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

Pozdrawiam

0

To napisz własny filtr który w przypadku poprawnego zalogowania ze strony logowania będzie kierował do odpowiedniego zasobu. Przykład masz w moim wcześniejszym poście. http://www.caucho.com/resin-3.0/config/webapp.xtp#filter

0

Witam

Dziękuję wszystkim za pomoc.

Obecnie testuję aplikację na ver. 3.1.2 GlassFish z NetBeans 7.2.

Konfiguracja na stronach www:

http://jugojava.blogspot.com/2011/02/jdbc-security-realm-with-glassfish-and.html
http://vizzdoom.net/2011/10/glassfish-uwierzytelnianie-zarzadzane-przez-kontener-aplikacji/

Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1