כל זה JAAS

האם אי פעם היית צריך ליצור מנגנון אימות כניסה ליישום? רוב הסיכויים הם שיש לך, וכנראה יותר מפעם אחת, כאשר כל יישום חדש קרוב, אך לא זהה, לזה הקודם. לדוגמה, יישום אחד עשוי להשתמש במסד נתונים של Oracle, אחר עשוי להשתמש באימות NT, ואחר, בספריית LDAP (פרוטוקול קל משקל הגישה לספרייה). האם זה לא יהיה נחמד לתמוך בכל מנגנוני האבטחה הללו מבלי לשנות קוד ברמת היישום?

עכשיו בעולם ג'אווה, אתה יכול להשתמש בשירות האימות וההסמכה של Java (JAAS). ה- API החדש יחסית היה הרחבה ב- J2SE (Java 2 Platform, Standard Edition) 1.3, הוא API API בליבה ב- J2SE 1.4, והוא גם חלק ממפרט J2EE (Java 2 Platform, Enterprise Edition) 1.3. במאמר זה נלמד את יסודות ה- JAAS ונראה לכם כיצד ליישם את JAAS ביעילות על יישומים בעולם האמיתי. ביססנו את היישום של מאמר זה על התנסויות משלנו בשילוב JAAS במערכת מבוססת Java קיימת, שהשתמשה ב- RDBMS (מערכת ניהול מסדי נתונים יחסיים) לאחסון פרטי כניסה למשתמש. עם JAAS תכננו מנגנוני כניסה ואימות חזקים יותר, גמישים ועקביות יותר.

תוכל להוריד קבוצה מלאה של דוגמאות עבודה ממשאבים למטה (כולל מקורות Java, JSPs (דפי JavaServer), תצורת JAAS, עם קבצי מסד נתונים ובניית סקריפטים). בדקנו דוגמאות אלה באמצעות שרת Resin עם JDBC (Java Database Connectivity) ובסיס הנתונים MySQL.

אימות ואישור Java: התמונה הגדולה

לפני JAAS, מודל האבטחה של Java עוצב בעיקר על ידי מקורו כשפה עצמאית לפלטפורמה ליישומים מבוזרים ברשת. בימייה הראשונה, Java קרובות הופיעה כקוד נייד, כגון יישומונים מבוססי דפדפן, ולכן, מודל האבטחה הראשוני התמקד בהגנה על משתמשים בהתבסס על שם קוד המקור ואת שיצר אותו. מנגנוני אבטחה מוקדמים של Java כגון SecurityManagers, מושג ארגז החול, חתימת קוד וקבצי מדיניות נועדו כולם להגן על המשתמשים מפני המערכת.

המצאת JAAS משקפת את התפתחות ג'אווה לשפת תכנות כללית, המשמשת ליישום יישומי לקוח ושרת מסורתיים הדורשים כניסה ובקרת גישה. JAAS מגן על המערכת מפני משתמשים בכך שהוא מאפשר או דוחה גישה על סמך מי או מה שמפעיל את התוכנית. בעוד JAAS יכול לבצע גם אימות וגם אישור, במאמר זה אנו מתמקדים בעיקר באימות.

JAAS יכול לפשט את פיתוח האבטחה שלך ב- Java על ידי הצבת שכבת הפשטה בין היישום שלך ומנגנוני אימות ואישור בסיסיים שונים. העצמאות הזו מפלטפורמות ואלגוריתמים מאפשרת לך להשתמש במנגנוני אבטחה שונים מבלי לשנות את קוד ברמת היישום שלך. כמו ברוב ממשקי ה- API של אבטחת Java, JAAS משיגה את עצמאות ההטמעה הזו באמצעות מסגרת נרחבת של ממשקי ספקי שירות ניתנים (SPI): קבוצה של מחלקות וממשקים מופשטים אליהם מפותחים יישומים ספציפיים.

איור 1 להלן נותן סקירה ברמה גבוהה על האופן שבו JAAS משיגה את יכולת התקע הזו. קוד שכבת היישום שלך עוסק בעיקר ב- LoginContext. מתחתיה LoginContextקבוצה של אחד או יותר מוגדרים באופן דינמי LoginModule, המטפלים באימות בפועל באמצעות תשתית האבטחה המתאימה.

JAAS מספק כמה LoginModuleיישומי הפניה , כגון JndiLoginModule; אתה יכול גם לפתח משלך, כפי שנעשה כאן עם RdbmsLoginModule. אנו נראה גם כיצד ניתן להגדיר במהירות יישום עם מבחר יישומים באמצעות קובץ תצורה פשוט.

בנוסף להיותם ניתנים לחיבור, JAAS ניתנת לערימה: בהקשר של כניסה יחידה, קבוצה של מודולי אבטחה יכולה להיערם זה על גבי זה, כל אחד מהם נקרא לפי סדר וכל אחד מקיים אינטראקציה עם תשתית אבטחה אחרת.

היבטים של JAAS מתוכננים על כמה תבניות אדריכליות ביטחוניות מוכרות ומסגרות קיימות. התכונה הניתנת לערימה, למשל, דומה בכוונה למסגרת ה- PAM (Unix Pluggable Authentication Module). מנקודת מבט עסקה, JAAS מאמץ התנהגויות הדומות לפרוטוקולי התחייבות דו-פאזיים (2PC). מושגי תצורת האבטחה של JAAS, כולל Policyקבצים Permissions, ומגיעים מחבילות האבטחה J2SE 1.2. JAAS גם לווה רעיונות ממסגרות אבטחה מבוססות אחרות, כגון תעודות X.509, שמהן Subjectנגזר השם (תוכלו ללמוד עוד על Subjectמאוחר יותר).

הערה: JAAS הוא רק אחד מכמה ממשקי API לאבטחה חדשים של Java. למידע נוסף על אבטחת Java, ראה בסרגל הצד "חידת האבטחה של Java" ומשאבים למטה.

JAAS בצד הלקוח והשרת

ניתן להחיל JAAS גם על הלקוח וגם על השרת. השימוש בו בצד הלקוח הוא פשוט, כפי שנדגים בקרוב. בצד השרת הדברים גדלים מעט יותר מורכבים. נכון לעכשיו, JAAS בשוק שרתי היישומים מעט לא עקבי; שרתי האפליקציות J2EE משתמשים ב- JAAS בצורה שונה במקצת, תלוי באיזה אתה משתמש. לדוגמא, JBossSX, המשתמשת בארכיטקטורה משלהם, משלבת יפה את JAAS במסגרת האבטחה הכוללת שלה (המפורט במאמר המעולה של סקוט סטארק ב- JavaWorld "שילוב תשתיות אבטחה עם JBossSX" (אוגוסט 2001)). עם זאת, למרות ש- WebLogic 6.x תומך ב- JAAS, הפרטים שונים זה מזה.

כדי שתוכל להבין את JAAS מנקודת מבט מצד השרת וגם מצד הלקוח, נדגים דוגמאות לשניהם במאמר זה. ולצורך פשטות בשרת, נשתמש בשרת היישומים של שרף כדי שנוכל להתחיל עם לוח נקי יותר (לשרף אכן יש תוכנית אימות ניתנת לשליחה, אך היא אינה תקנית, ולכן השימוש ב- JAAS מעניק לנו ניידות רבה יותר אפשרויות בהמשך).

ליבת JAAS

כדי להתחיל לעבוד עם JAAS, תחילה עליך לוודא שהוא מותקן. J2SE 1.4 כבר כולל את JAAS; J2SE 1.3 לא. אם ברצונך להמשיך להשתמש ב- J2SE 1.3, הורד את JAAS מ- Sun Microsystems. לאחר שתוריד ותתקין את JAAS לספריה נתונה, תראה ספריה משנה הנקראת lib, המכילה קובץ אחד בשם jaas.jar. יהיה עליך להוסיף קובץ זה לשביל הכיתה שלך או להעתיק אותו לספריית התוספות JRE שלך (Java Runtime Environment) (בתוך \lib\ext, היכן המיקום של JRE שלך). לאחר מכן אתה מוכן ל- JAAS. הערה: אם אתה משתמש בשרת יישומים, ייתכן שהוא כבר כולל JAAS. עיין בתיעוד השרת שלך לקבלת פרטים.

בכל אחת מהגישות הללו, שים לב שאתה יכול לשנות חלק מהגדרות מאפייני המערכת הקשורות ל- JAAS (כמו גם הגדרות אבטחה רבות אחרות של Java) בקובץ מאפייני האבטחה של Java. קובץ זה,, java.securityממוקם /lib/securityבספריה וכתוב בתבנית הקובץ הרגילה של מאפייני Java.

השימוש באימות JAAS מהיישום שלך כולל בדרך כלל את השלבים הבאים:

  1. ליצור LoginContext
  2. העבר אופציונלי CallbackHandlerל - LoginContextלאיסוף או עיבוד נתוני אימות
  3. בצע אימות באמצעות פנייה LoginContextשל" login()שיטה
  4. בצע פעולות מיוחדות באמצעות המוחזר Subject(בהנחה שהתחברות מצליחה)

הנה דוגמא מינימלית:

LoginContext lc = LoginContext חדש ("MyExample"); נסה את {lc.login (); } לתפוס (LoginException) {// האימות נכשל. } // האימות הצליח, כעת נוכל להמשיך. // אנו יכולים להשתמש בנושא שהוחזר אם נרצה. נושא משנה = lc.getSubject (); Subject.doAs (משנה, MyPrivilegedAction חדש ());

מתחת לכיסויים מתרחשים כמה דברים אחרים:

  1. במהלך האתחול, LoginContextהמוצא מוצא את ערך "MyExample"התצורה בקובץ תצורה של JAAS (שקבעתם) כדי לקבוע אילו LoginModuleטעונים (ראו איור 2)
  2. במהלך הכניסה, את LoginContextקוראת לכל LoginModules" login()השיטה
  3. כל login()שיטה מבצעת את האימות או מגייסת אCallbackHandler
  4. CallbackHandlerשימושים אחד או יותר Callbackשל אינטראקציה עם המשתמש ולאסוף קלט
  5. Subjectמופע חדש מאוכלס בפרטי אימות כגון Principals ותעודות

נסביר להלן פרטים נוספים, אך ראשית, בואו נסתכל על שיעורי JAAS והממשקים העיקריים המעורבים בתהליך. אלה מחולקים בדרך כלל לשלוש הקבוצות הבאות:

טבלה 1. מחלקות וממשקי JAAS

מְשׁוּתָף Subject, Principal, אישורים (אישורים הם לא כל כיתה ספציפית, אבל יכול להיות כל אובייקט)
אימות LoginContext, LoginModule, CallbackHandler,Callback
הרשאה Policy, AuthPermission,PrivateCredentialPermission

רוב המחלקות והממשקים הללו נמצאים javax.security.authבחבילות המשנה של החבילה, עם כמה יישומים שנבנו מראש com.sun.security.authבחבילה, הכלולים רק ב- J2SE 1.4.

הערה: מכיוון שאנו מתמקדים באימות במאמר זה, איננו מתעמקים בשיעורי ההרשאה.

נפוץ: נושאים, מנהלים ותעודות

Subjectבכיתה מייצגת יישות אותנטית: שירות של משתמש קצה או מנהל, או אינטרנט, מכשיר, או תהליך אחר. השיעור מכיל שלוש קבוצות של סוגי מידע אבטחה:

  • זהויות: בשינה בצורה אחד או יותר Principalשל
  • אישורים ציבוריים: כגון שם או מפתחות ציבוריים
  • אישורים פרטיים: כמו סיסמאות או מפתחות פרטיים

Principals represent Subject identities. They implement the java.security.Principal interface (which predates JAAS) and java.io.Serializable. A Subject's most important method is getName(), which returns an identity's string name. Since a Subject instance contains an array of Principals, it can thus have multiple names. Because a social security number, login ID, email address, and so on, can all represent one user, multiple identities prove common in the real world.

The last element here, credential, is not a class or an interface, but can be any object. Credentials can include any authentication artifact, such as a ticket, key, or password, that specific security systems might require. The Subject class maintains unique Sets of private and public credentials, which can be retrieved with methods such as getPrivateCredentials() and getPublicCrendentials(). These methods are more often used by security subsystems than at the application layer.

Authentication: LoginContext

Your application layer uses LoginContext as its primary class for authenticating Subjects. LoginContext also represents where JAAS's dynamic pluggability comes into play, because when you construct a LoginContext, you specify a named configuration to load. The LoginContext typically loads the configuration information from a text file, which in turn tells the LoginContext which LoginModules to use during login.

The three commonly used methods in LoginContext are:

Table 2. LoginContext methods

login() Performs login, a relatively complex step that invokes all LoginModules specified for this configuration. If it succeeds, it creates an authenticated Subject. If it fails, it throws a LoginException.
getSubject() Returns the authenticated Subject.
logout() Logs out the authenticated Subject and removes its Principals and credentials.

We will show how to use these methods later.

Authentication: LoginModule

LoginModule is the interface to specific authentication mechanisms. J2SE 1.4 ships with a set of ready-to-use LoginModules, including:

Table 3. LoginModules in J2SE 1.4

JndiLoginModule Verifies against a directory service configured under JNDI (Java Naming and Directory Interface)
Krb5LoginModule Authenticates using Kerberos protocols
NTLoginModule Uses the current user's NT security information to authenticate
UnixLoginModule Uses the current user's Unix security information to authenticate

Along with these modules comes a set of corresponding concrete Principal implementations in the com.sun.security.auth package, such as NTDomainPrincipal and UnixPrincipal.

The LoginModule interface has five methods:

Table 4. LoginModule methods

initialize() Called after the LoginModule is constructed.
login() Performs the authentication.
commit() Called by the LoginContext after it has accepted the results from all LoginModules defined for this application. We assign Principals and credentials to the Subject here.
abort() Called when any LoginModule for this application fails (even though earlier ones in sequence may have succeeded—thus akin to a 2PC model). No Principals or credentials are assigned to the Subject.
logout() Removes the Principals and credentials associated with the Subject.

The application layer calls none of these methods directly—the LoginContext invokes them as needed. Our example below will elaborate on these methods' implementations.

Authentication: CallbackHandlers and Callbacks

CallbackHandlers ו- Callbacks מאפשרים LoginModuleלאסוף את פרטי האימות הדרושים ממשתמש או מערכת, תוך השארת עצמאי ממנגנון האינטראקציה בפועל. אנו ננצל את היכולת הזו בעיצוב שלנו - שלנו RdbmsLoginModuleלא תלוי איך מתקבלים אישורי המשתמש (שם משתמש / סיסמה) ולכן ניתן להשתמש בהם בסביבות היישום השונות שנמחיש (משורת הפקודה או מ- JSP) .