2009-09-24 12 views
35

में मूल सुरक्षा मैं एक साधारण लॉगिन एप्लिकेशन देखना चाहता हूं, हालांकि this जितना सरल नहीं है।जेएसएफ

मैं जो हासिल करना चाहता हूं वह यह समझने के लिए है कि जेएसएफ कैसे काम करता है, मैंने बहुत सी एएसपी.नेट विकसित की है जहां आपके पास कोड है और आप यह जांच सकते हैं कि लॉग इन पर कोई सत्र बनाया गया था या नहीं।

जेएसएफ में एक समान समाधान बहुत अच्छा होगा।

यह मूलतः है मैं क्या हासिल करना चाहते:

  • लॉग इन पेज
  • अगर ठीक
    • सत्र बनाएँ और वापसी "सफलता"
  • यदि असफल
    • वापसी "विफलता"

एक ("सफलता" और विफलता चेहरे-config.xml पर मैप किए जाते) सफलता-पेज मैं कुछ है कि उपयोगकर्ता के प्रवेश चाहते हैं पर, तो यदि आपको सही सत्र नहीं मिला है तो "success.xspx" पर नेविगेट करने में सक्षम नहीं होना चाहिए।

+1

संबंधित: http://stackoverflow.com/questions/2206911/best-way-for-user- प्रमाणीकरण-on-javaee-6-using-jsf-2-0/2207147#2207147 या यदि आप खुले हैं शिरो जैसे तीसरे पक्ष के पुस्तकालयों के लिए, फिर http://balusc.blogspot.com/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html – BalusC

उत्तर

44

कोर जेएसएफ में घटक rendered जैसी चीजों का उपयोग करने में सक्षम होने से परे भूमिका-आधारित सुरक्षा की दिशा में कोई अंतर्निहित प्रमाणीकरण कार्यक्षमता नहीं है।

डिफ़ॉल्ट रूप से, एक जेएसएफ एप्लिकेशन उसी कंटेनर-प्रबंधित सुरक्षा तंत्र पर निर्भर करता है जिसमें वेब घटक होता है जिसमें यह शामिल होता है (JEE5 tutorial)। Seam जैसे तृतीय पक्ष ढांचे विकल्प प्रदान कर सकते हैं।

यदि आप अपनी खुद की एप्लिकेशन सुरक्षा जोड़ना चाहते हैं, तो servlet filter सरल तंत्र में से एक है।

<filter> 
    <filter-name>AuthenticationFilter</filter-name> 
    <filter-class>restricted.AuthenticationFilter</filter-class> 
    </filter> 
    <filter-mapping> 
    <filter-name>AuthenticationFilter</filter-name> 
    <url-pattern>/restricted/*</url-pattern> 
    </filter-mapping> 

फिल्टर वर्ग कार्यान्वयन:

public class AuthenticationFilter implements Filter { 
    private FilterConfig config; 

    public void doFilter(ServletRequest req, ServletResponse resp, 
     FilterChain chain) throws IOException, ServletException { 
    if (((HttpServletRequest) req).getSession().getAttribute(
     AuthenticationBean.AUTH_KEY) == null) { 
     ((HttpServletResponse) resp).sendRedirect("../restricted_login.faces"); 
    } else { 
     chain.doFilter(req, resp); 
    } 
    } 

    public void init(FilterConfig config) throws ServletException { 
    this.config = config; 
    } 

    public void destroy() { 
    config = null; 
    } 
} 

एक लॉगिन सेम faces-config.xml में परिभाषित:

public class AuthenticationBean { 
    public static final String AUTH_KEY = "app.user.name"; 

    private String name; 
    public String getName() { return name; } 
    public void setName(String name) { this.name = name; } 

    public boolean isLoggedIn() { 
    return FacesContext.getCurrentInstance().getExternalContext() 
     .getSessionMap().get(AUTH_KEY) != null; 
    } 

    public String login() { 
    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(
     AUTH_KEY, name); 
    return "secret"; 
    } 

    public String logout() { 
    FacesContext.getCurrentInstance().getExternalContext().getSessionMap() 
     .remove(AUTH_KEY); 
    return null; 
    } 
} 

इस फिल्टर restricted निर्देशिका के रूप में web.xml में परिभाषित के तहत संसाधनों की रक्षा करता है वें में जेएसएफ लॉगिन फॉर्म ई restricted_login.jsp पेज:

<f:view> 
    <p><a href="restricted/secret.faces">try to go to secret 
    page</a></p> 
    <h:form> 
    Username: 
    <h:panelGroup rendered="#{not authenticationBean.loggedIn}"> 
     <h:inputText value="#{authenticationBean.name}" /> 
     <h:commandButton value="login" 
      action="#{authenticationBean.login}" /> 
     </h:panelGroup> 
     <h:commandButton value="logout" 
     action="#{authenticationBean.logout}" 
     rendered="#{authenticationBean.loggedIn}" /> 
    </h:form> 
    </f:view> 

(रीडायरेक्ट URL/तंत्र बल्कि सबसे अच्छा अभ्यास के किसी भी प्रकार से संक्षिप्तता के लिए चुना गया था; अधिक विकल्पों के लिए Servlet API देखें।)

+0

क्या आप यह स्पष्ट कर सकते हैं कि यह कैसे अलग है कंटेनर प्रबंधित सुरक्षा? और प्रत्येक के वकील/विवादों पर विचार करने के बाद एक दूसरे को कैसे पसंद किया जाए? –

+0

@Marcos - जो वास्तव में इसके स्वयं के प्रश्न होने का हकदार है, संभवतः इसे संदर्भित करना। – McDowell

+0

असल में मैंने पहले से ही कुछ इसी तरह पोस्ट किया था: http: //stackoverflow.com/questions/7872265/protected-urls-leaking-unprotected-components-of-the-webapge-to-unauthenticated/7875236#7875236 –

4

यदि आप थोड़ा अधिक उन्नत दृष्टिकोण आजमाने की इच्छा रखते हैं तो मैं वसंत-सुरक्षा + जेएसएफ की तलाश करने का सुझाव देता हूं। यह एक सम्मोहन की तरह काम करता है।

आप अपना आवेदन लिख सकते हैं जैसे कि यह सुरक्षा में नहीं था और फिर केवल उन क्षेत्रों को कॉन्फ़िगर करें जिन्हें पहलुओं का उपयोग करके संरक्षित किया जाना चाहिए।

स्प्रिंग सुरक्षा: http://static.springsource.org/spring-security/site/

एक ट्यूटोरियल: http://ocpsoft.com/java/acegi-spring-security-jsf-login-page/

3

सबसे अच्छा यह कंटेनर का उपयोग करना होगा करने के लिए जिस तरह से सुरक्षा में कामयाब रहे।

Here is a tutorialglassfish और jsf के साथ इसे प्राप्त करने के तरीके पर कैसे।

2

यदि आप टेम्पलेट का उपयोग करते हैं, तो मुझे पता चला है कि आपको वास्तव में फ़िल्टर की आवश्यकता नहीं है।

index.jsp

<jsp:forward page="startup.faces"></jsp:forward> 

startup.xhtml (.faces), वास्तव में एक स्क्रीन प्रदर्शित करने का प्रयास नहीं है, यह लोड पर जावास्क्रिप्ट startupSubmit() calles और उस बटन पर क्लिक करता। यह StartupBean.java में सीधे विधि प्रारंभ() पर प्रवाह भेजता है।

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0  Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
. 
. 
<script type="text/javascript"> 
function startupSubmit() { 
    **document.getElementById('startupForm:startupBtn').click();** 
} 
</script> 
<h:body onload="startupSubmit()"> 
<h:form id="startupForm"> 
<p:commandButton id="startupBtn" value="" action="#{startupBean.start}" ajax="false" /> 
</h:form> 
</h:body> 
</html> 

StartupBean.java (नीचे टेम्पलेट.एक्सएचटीएम का हिस्सा नहीं है)। स्टार्टअपबीन में स्टार्ट() विधि एक वैरिएबल सेट करती है जिसे सत्य के लिए अधिकृत कहा जाता है (यह गलत पर डिफ़ॉल्ट होता है), फिर first.xhtml पर कूदता है। आप किसी भी मानदंड का उपयोग कर सकते हैं जिसे आप निर्धारित करना चाहते हैं कि क्या अधिकृत सत्य पर सेट है ... जैसे लॉगिन मानदंड।

package gov.irs.eservices.managementBeans; 

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.SessionScoped; 

@ManagedBean(name="startupBean") 
@SessionScoped 
public class StartupBean { 

private boolean authorized; 

public StartupBean() { 
} 

public String start() { 
    **setAuthorized(true);** 
    return "first"; 
} 

public boolean isAuthorized() { 
    return authorized; 
} 

public void setAuthorized(boolean authorized) { 
    this.authorized = authorized; 
} 
} 

template.xhtml। टेम्पलेट.एक्सएचटीएमएल में, केवल फॉर्म के अंदर, आप एच: या पी: पैनल ग्रिड डालते हैं और स्टार्टअप बीन.अधिकृत होने पर ही इसे प्रस्तुत करते हैं। टेम्पलेट में निहित पृष्ठों पर उपयोगकर्ता एकमात्र तरीका प्राप्त कर सकता है यदि वे पहले StartupBean.java के माध्यम से आते हैं।

<f:view> 
<div id="container"> 
<h:form id="templateForm"> 
**<p:panelGrid rendered="#{startupBean.authorized}">** 
    <div id="header"> 
     <ui:include src="header.xhtml" /> 
    </div> 

    <div id="wrapper"> 
     <div id="firstId"> 
      <ui:insert name="first"></ui:insert> 
     </div> 
. 
. <!-- MORE PAGES --> 
. 
. 
    </div> 

    <div id="footer"> 
     <ui:include src="footer.xhtml" /> 
    </div> 
</p:panelGrid> 
</h:form> 
</div>  
</f:view> 

तो, यह मेरा समाधान है। मैंने इसे बहुत अच्छी तरह से परीक्षण किया है और ऐसा लगता है कि यह ठीक काम करता है।

+0

'ManagedBean 'स्टार्टअप बीन 'में * नाम * विशेषता अनावश्यक है क्योंकि यह डिफ़ॉल्ट रूप से यह नाम प्राप्त करेगी। – rbento