জাভা EE / JSF- এ j_security_check ব্যবহার করে ব্যবহারকারীর প্রমাণীকরণ সম্পাদন করা হচ্ছে


156

আমি ভাবছি যে জেএসএফ ২.০ (এবং যদি কোনও উপাদান উপস্থিত থাকে) এবং জাভা ইই 6 কোর মেকানিজম (জিপিএতে থাকা ব্যবহারকারী তথ্যের সাথে জাভা ইই 6 কোর মেকানিজম (লগইন / চেকের অনুমতি / লগআউটগুলি) ব্যবহার করে যা ওয়েব অ্যাপ্লিকেশন ব্যবহারকারীর অনুমোদনের বিষয়ে বর্তমান পদ্ধতির কী? সত্তা। ওরাকল জাভা ইই টিউটোরিয়ালটি এটির জন্য কিছুটা স্পারস (কেবল সার্ভলেটগুলি পরিচালনা করে)।

এটি স্প্রিং-সিকিউরিটি (এসিগি), বা সিমের মতো পুরো অন্যান্য কাঠামোটি ব্যবহার না করেই সম্ভব হলেও নতুন জাভা ইই 6 প্ল্যাটফর্ম (ওয়েব প্রোফাইল) দিয়ে আশাবাদী থাকার চেষ্টা করছে।

উত্তর:


85

ওয়েবে অনুসন্ধান করার পরে এবং বিভিন্ন উপায়ে চেষ্টা করার পরে, আমি জাভা EE 6 প্রমাণীকরণের জন্য যা পরামর্শ দেব তা এখানে:

সুরক্ষা ক্ষেত্র সেট আপ করুন:

আমার ক্ষেত্রে, আমি ডাটাবেসে ব্যবহারকারী ছিল। সুতরাং আমি একটি জেডিবিসি রিয়েলম তৈরি করতে এই ব্লগ পোস্টটি অনুসরণ করেছি যা ব্যবহারকারীর নাম এবং এমডি 5-হ্যাশ পাসওয়ার্ডের ভিত্তিতে আমার ডাটাবেস সারণিতে প্রমাণীকরণ করতে পারে:

http://blog.gamatam.com/2009/11/jdbc-realm-setup-with-glassfish-v3.html

দ্রষ্টব্য: পোস্টে ব্যবহারকারী এবং ডাটাবেজে একটি গ্রুপ টেবিল সম্পর্কে কথা বলা হয়েছে। ডেটাবেসটিতে জাভ্যাক্স.পার্স্পাস্টি টীকাগুলির মাধ্যমে ম্যাপযুক্ত ইউজার টাইপ এনাম অ্যাট্রিবিউটের সাথে আমার ব্যবহারকারীর ক্লাস ছিল। আমি ব্যবহারকারী এবং গ্রুপগুলির জন্য একই টেবিলের সাথে রাজ্যটি কনফিগার করেছি, ইউজারটাইপ কলামটি গ্রুপ কলাম হিসাবে ব্যবহার করেছি এবং এটি দুর্দান্ত কাজ করেছে।

ফর্ম প্রমাণীকরণ ব্যবহার করুন:

তবুও উপরের ব্লগ পোস্টটি অনুসরণ করে, আপনার ওয়েব.এক্সএমএল এবং সান-ওয়েব.এক্সএমএল কনফিগার করুন, তবে বেসিক প্রমাণীকরণ ব্যবহারের পরিবর্তে, ফরম ব্যবহার করুন (আসলে আপনি কোনটি ব্যবহার করেন তা বিবেচ্য নয়, তবে আমি ফর্মটি ব্যবহার করে শেষ করেছি)। জেএসএফ নয়, মানক এইচটিএমএল ব্যবহার করুন।

তারপরে ডাটাবেস থেকে ব্যবহারকারীর তথ্য অলস করে শুরু করার জন্য উপরে বালাসকের টিপটি ব্যবহার করুন। তিনি মুখের প্রসঙ্গে প্রিন্সিপালকে একটি পরিচালিত শিমের মধ্যে এটি করার পরামর্শ দিয়েছিলেন। আমি পরিবর্তে, প্রতিটি ব্যবহারকারীর জন্য সেশন তথ্য সংরক্ষণ করার জন্য একটি রাষ্ট্রীয় সেশন বিন ব্যবহার করেছি, সুতরাং আমি সেশনের প্রসঙ্গটি ইনজেকশন করেছি:

 @Resource
 private SessionContext sessionContext;

অধ্যক্ষের সাথে, আমি ব্যবহারকারীর নামটি পরীক্ষা করতে এবং EJB সত্তা পরিচালককে ব্যবহার করে আমার SessionInformationEJB তে ডাটাবেস এবং সঞ্চয় থেকে ব্যবহারকারী তথ্য পেতে পারি ।

প্রস্থান:

লগআউট করার সর্বোত্তম উপায়টির জন্যও আমি চারপাশে তাকিয়ে ছিলাম। আমি যে সেরাটি খুঁজে পেয়েছি তা হ'ল সার্ভলেট ব্যবহার করা:

 @WebServlet(name = "LogoutServlet", urlPatterns = {"/logout"})
 public class LogoutServlet extends HttpServlet {
  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   HttpSession session = request.getSession(false);

   // Destroys the session for this user.
   if (session != null)
        session.invalidate();

   // Redirects back to the initial page.
   response.sendRedirect(request.getContextPath());
  }
 }

যদিও আমার উত্তরটি প্রশ্নের তারিখটি বিবেচনা করে সত্যিই দেরি করেছে, আমি আশা করি এটি অন্যান্য লোকদেরও এখানে যেমন গুগল থেকে শেষ হয়েছিল, ঠিক তেমনই সহায়তা করেছে।

Ciao,

ভেটর সৌজা


15
একটি ছোট্ট পরামর্শের শব্দ: আপনি অনুরোধ.গ্রেটসেশন (মিথ্যা) এবং কলটি অবৈধ () ব্যবহার করছেন calling অনুরোধ.সেটসেশন (মিথ্যা) কোনও অধিবেশন না থাকলে শূন্য ফিরে আসতে পারে। এটি প্রথমে নাল কিনা ভাল কিনা তা পরীক্ষা করে দেখুন;)
আরজান টিজমস

@ ভিজিটর: হাই..আপনি যখন ধারক ভিত্তিক সুরক্ষা থেকে শিরো বা অন্যদের মতো বিকল্পের দিকে চলে যাওয়া ভাল তখন আপনি কিছু বলতে চান? এখানে আরও কেন্দ্রীভূত প্রশ্ন দেখুন: স্ট্যাকওভারফ্লো.com
রজত গুপ্ত

দেখে মনে হচ্ছে গ্লাস ফিশ জেডিবিসি রিয়েলমে সল্টযুক্ত পাসওয়ার্ড হ্যাশগুলি সংরক্ষণ করে না। সেক্ষেত্রে এটি ব্যবহার করা কি সত্যিই সেরা অনুশীলন?
Lii

দুঃখিত, আপনাকে সাহায্য করতে পারে না। আমি গ্লাসফিশ বিশেষজ্ঞ নই। লোকেরা কী বলে তা দেখতে হয়তো নতুন প্রশ্নে সেই প্রশ্নটি জিজ্ঞাসা করুন?
ভেটর ই। সিলভা সুজা

1
লি, আপনি গ্লাস ফিশের ধারকটি ব্যবহার করে সল্ট দিয়ে কাজ করতে পারেন। কোনও হ্যাশ ব্যবহার না করার জন্য আপনার হেলমে কনফিগার করুন। এটি পাসওয়ার্ডের জন্য আপনি যে সরল মান সন্নিবেশ করেছেন তার সাথে তুলনা করবে HttpServletResponse#login(user, password), আপনি কেবলমাত্র ডিবি ব্যবহারকারীর লবণ, পুনরাবৃত্তিগুলি এবং সল্টিংয়ের জন্য যা কিছু ব্যবহার করতে পারেন, সেই লব ব্যবহার করে ব্যবহারকারী যে পাসওয়ার্ডটি প্রবেশ করিয়েছে তা হ্যাশ এবং তারপরে কনটেইনারকে প্রমাণীকরণ করতে বলবে HttpServletResponse#login(user, password)
এম্পোরটেলা

152

আমি মনে করি আপনি ডিপ্লোয়মেন্ট ডেসক্রিপটর এবং ব্যবহার করে ফর্ম ভিত্তিক প্রমাণীকরণ চান ।j_security_check

আপনি ঠিক একই পূর্বনির্ধারিত ক্ষেত্রের নামগুলি ব্যবহার করে j_usernameএবং j_passwordটিউটোরিয়ালটিতে প্রদর্শিত হিসাবে জেএসএফ এ এটি করতে পারেন ।

যেমন

<form action="j_security_check" method="post">
    <h:outputLabel for="j_username" value="Username" />
    <h:inputText id="j_username" />
    <br />
    <h:outputLabel for="j_password" value="Password" />
    <h:inputSecret id="j_password" />
    <br />
    <h:commandButton value="Login" />
</form>

ইতিমধ্যে লগইন হয়েছে কিনা তা Userপরীক্ষা করার জন্য আপনি গেটরে অলস লোডিং করতে পারেন Userএবং যদি না থাকে, তবে Principalঅনুরোধে উপস্থিত আছেন কিনা তা পরীক্ষা করে দেখুন এবং তারপরে, তার Userসাথে যুক্ত হয়ে যান j_username

package com.stackoverflow.q2206911;

import java.io.IOException;
import java.security.Principal;

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

@ManagedBean
@SessionScoped
public class Auth {

    private User user; // The JPA entity.

    @EJB
    private UserService userService;

    public User getUser() {
        if (user == null) {
            Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
            if (principal != null) {
                user = userService.find(principal.getName()); // Find User by j_username.
            }
        }
        return user;
    }

}

Userস্পষ্টত দ্বারা JSF এল অ্যাক্সেসযোগ্য #{auth.user}

লগআউট করতে একটি করুন HttpServletRequest#logout()(এবং Userবাতিল করুন!)। এর মাধ্যমে HttpServletRequestআপনি জেএসএফ- এর একটি হ্যান্ডেল পেতে পারেন ExternalContext#getRequest()। আপনি স্রেফ পুরোপুরি অবৈধ করতে পারেন।

public String logout() {
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    return "login?faces-redirect=true";
}

অবশিষ্টাংশের জন্য (ব্যবহারকারীর সংজ্ঞা, বিবরণীর বিবরণকারী এবং রাজ্যের ক্ষেত্রে ভূমিকা এবং সীমাবদ্ধতা) কেবল জাভা ইই 6 টি টিউটোরিয়াল এবং সার্ভলেটকন্টেইনার ডকুমেন্টেশনটি যথাযথভাবে অনুসরণ করুন।


আপডেট : আপনি নতুন সার্লেট ৩.০ ব্যবহার করার HttpServletRequest#login()পরিবর্তে একটি প্রোগ্রাম্যাটিক লগইন j_security_checkকরতে ব্যবহার করতে পারেন যা কিছু সার্লেটকন্টেইনারে কোনও প্রেরণকারীর দ্বারা প্রতি-সেয়ে পৌঁছতে পারে না। এক্ষেত্রে আপনি একটি উপযুক্ত জেএসএফ ফর্ম এবং একটি শিম usernameএবং passwordবৈশিষ্ট্য এবং এমন loginপদ্ধতি যা দেখতে দেখতে ব্যবহার করতে পারেন :

<h:form>
    <h:outputLabel for="username" value="Username" />
    <h:inputText id="username" value="#{auth.username}" required="true" />
    <h:message for="username" />
    <br />
    <h:outputLabel for="password" value="Password" />
    <h:inputSecret id="password" value="#{auth.password}" required="true" />
    <h:message for="password" />
    <br />
    <h:commandButton value="Login" action="#{auth.login}" />
    <h:messages globalOnly="true" />
</h:form>

এবং এই ভিউটি স্কপড ম্যানেজ করা শিম যা প্রাথমিকভাবে অনুরোধ করা পৃষ্ঠাটি মনে রাখে:

@ManagedBean
@ViewScoped
public class Auth {

    private String username;
    private String password;
    private String originalURL;

    @PostConstruct
    public void init() {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        originalURL = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);

        if (originalURL == null) {
            originalURL = externalContext.getRequestContextPath() + "/home.xhtml";
        } else {
            String originalQuery = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_QUERY_STRING);

            if (originalQuery != null) {
                originalURL += "?" + originalQuery;
            }
        }
    }

    @EJB
    private UserService userService;

    public void login() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext externalContext = context.getExternalContext();
        HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();

        try {
            request.login(username, password);
            User user = userService.find(username, password);
            externalContext.getSessionMap().put("user", user);
            externalContext.redirect(originalURL);
        } catch (ServletException e) {
            // Handle unknown username/password in request.login().
            context.addMessage(null, new FacesMessage("Unknown login"));
        }
    }

    public void logout() throws IOException {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        externalContext.invalidateSession();
        externalContext.redirect(externalContext.getRequestContextPath() + "/login.xhtml");
    }

    // Getters/setters for username and password.
}

এই পদ্ধতি Userদ্বারা JSF এল অ্যাক্সেসযোগ্য #{user}


1
আমি একটি দাবি অস্বীকার করার জন্য প্রশ্নটি আপডেট করেছি যাতে প্রেরণ করা j_security_checkসমস্ত সার্লেটলেট কনটেনারগুলিতে কাজ না করে।
বালুসসি

1
ওয়েব অ্যাপ্লিকেশনগুলির সাথে প্রোগ্রাম্যাটিক সুরক্ষা ব্যবহার সম্পর্কিত জাভা টিউটোরিয়াল থেকে লিঙ্ক: java.sun.com/javaee/6/docs/tutorial/doc/gjiie.html ( সার্লেটস ব্যবহার করে): একটি সার্লেট ক্লাসে আপনি ব্যবহার করতে পারেন: @WebServlet(name="testServlet", urlPatterns={"/ testServlet "}) @ServletSecurity(@HttpConstraint(rolesAllowed = {"testUser", "admin”})) এবং প্রতি পদ্ধতিতে স্তর: @ServletSecurity(httpMethodConstraints={ @HttpMethodConstraint("GET"), @HttpMethodConstraint(value="POST", rolesAllowed={"testUser"})})
নেজেক

3
আর তোমার কথা হচ্ছে ..? এটি জেএসএফ-এ প্রযোজ্য কিনা? ঠিক আছে, জেএসএফ-এ কেবল একটি সার্লেট রয়েছে, FacesServletএবং আপনি এটি পরিবর্তন করতে পারবেন না (এবং চান না)।
BalusC

1
@ বালুসসি - আপনি যখন বলছেন উপরেরটি সর্বোত্তম উপায় হ'ল আপনি কী_সিকিউরিটি_চেক বা প্রোগ্রাম্যাটিক লগইন ব্যবহার করছেন?
সিমগিনিজার

3
@ সিমজিনিয়ার: অনুরোধ করা ইউআরএল একটি নাম হিসাবে অনুরোধ হিসাবে হিসাবে নির্ধারিত হিসাবে নির্ধারিত হিসাবে উপলব্ধ RequestDispatcher.FORWARD_REQUEST_URI। অনুরোধ বৈশিষ্ট্যগুলি জেএসএফের দ্বারা উপলব্ধ ExternalContext#getRequestMap()
বালাসসি

7

এটি উল্লেখ করা উচিত যে এটি সামনের নিয়ন্ত্রণকারীর কাছে প্রমাণীকরণের সমস্যাগুলি পুরোপুরি ছেড়ে দেওয়ার বিকল্প, যেমন একটি অ্যাপাচি ওয়েবসার্ভার এবং পরিবর্তে HttpServletRequest.getRemoteUser () মূল্যায়ন করা, যা REMOTE_USER এনভায়রনমেন্ট ভেরিয়েবলের JAVA উপস্থাপনা। এটি শিবলোলেথ প্রমাণীকরণের মতো ডিজাইনে পরিশীলিত লগের অনুমতি দেয়। একটি ওয়েব সার্ভারের মাধ্যমে একটি সার্লেট পাত্রে অনুরোধগুলি ফিল্টার করা উত্পাদন পরিবেশের জন্য একটি ভাল নকশা, প্রায়শই মোড_জেকে এটি করতে ব্যবহৃত হয়।


4

HttpServletRequest.login সেশনে প্রমাণীকরণের স্থিতি সেট করে না তা ইস্যুটি 3.0.1 এ স্থির করা হয়েছে। সর্বশেষ সংস্করণে গ্লাসফিশ আপডেট করুন এবং আপনার কাজ শেষ।

আপডেট করা বেশ সোজা:

glassfishv3/bin/pkg set-authority -P dev.glassfish.org
glassfishv3/bin/pkg image-update

4
লিঙ্কটি নষ্ট হয়ে গেছে। আপনি কোন ইস্যুর কথা বলছেন?
একযোগে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.