Apache Shiro第1部分–基础

Apache Shiro (最初称为JSecurity)是Java安全框架。 它被接受并于2010年成为Apache顶级项目。它的目标是功能强大且易于使用。

该项目正在积极开发中,用户和开发人员的邮件列表均处于活动状态。 最重要的区域记录在其网页上。 但是,它在文档上有很多空白。 仅从文档中就不可能学会使用大多数Shiro功能。 幸运的是,该代码的注释很好,在我尝试过的地方也很容易阅读。

Shiro的主要功能是:

  • 验证,
  • 授权,
  • 密码学
  • 会话管理。

在本文中,我们尝试演示Shiro的各种功能。 我们从简单的不安全Web应用程序开始,然后向其中添加安全功能。 所有代码均在Github上的SimpleShiroSecuredApplication项目中可用。
不安全的应用程序

不安全的应用程序代码位于unsecured_application分支中。 应用程序代表一个虚构公司的内部系统。 该公司有四个部门:

  • 管理员,
  • 修理工
  • 科学家们,
  • 销售。

每个部门都有自己的页面。 每个页面都包含用户用来完成其工作的按钮。 当用户按下按钮时,工作就完成了。 例如,任何维修人员都可以转到维修人员页面,然后按“维修冰箱”按钮。 该按钮将修复冰箱并显示成功消息。

每个用户都有自己的帐户页面。 帐户页面包含用户的私人数据。 由于不安全的应用程序尚无用户,因此帐户页面不执行任何操作。 此外,还有一个页面包含所有应用程序功能。 任何人都可以做的所有事情都可以在此页面上完成。

任何人都可以做任何工作并查看所有页面 。示例应用程序在测试类RunWaitTest中运行。 以这种方式使用单元测试不是最佳实践,但现在并不重要。 如果您运行该类,则该应用程序将位于http:// localhost:9180 / simpleshirosecuredapplication / url中。

添加身份验证

首先,我们必须验证用户的身份。 最简单,最标准的身份验证是通过用户名和密码来完成的。 用户填写其用户名和密码,然后系统验证提供的值是否与某个用户帐户匹配。

对于最简单的应用程序,将用户名和密码存储在纯文本文件中就足够了。 在更现实的情况下,用户名和密码存储在持久性存储中,或者通过其他系统(例如ldap或活动目录)进行验证。 Shiro支持所有提到的身份验证方法。 如果开箱即用的身份验证功能不足,则可以使用自己的验证实现来扩展框架。

在本章中,我们将基于用户名和密码的身份验证添加到应用程序中。 用户名和密码存储在静态纯文本Shiro ini文件中。

新要求:可以登录和注销用户。 该应用程序仅可用于登录用户。 成功登录会将用户重定向到他自己的帐户页面。 所有登录用户仍然可以访问所有应用程序功能和页面。

所需步骤:

  • 添加Apache Shiro,
  • 创建登录页面,
  • 配置用户和密码,
  • 创建注销页面。

添加Apache Shiro

Shiro通过Servlet过滤器集成到Web应用程序中。 过滤器在servlet之前拦截请求和响应,并执行所有必要的任务(例如,标识当前登录的用户,将登录的用户附加到当前线程等)。 默认的Shiro筛选器提供基本的安全功能,例如:

  • 强制用户登录,
  • 执行ssl,
  • 检查页面访问权限。

如果您想了解有关默认Shiro过滤器的更多信息,那么最好的起点是DefaultFilter枚举。 它列出了所有默认可用的Shiro过滤器。 如果这些不足以满足您的需求,则可以创建自定义的。

我们将使用高度可配置的IniShiroFilter 。 它从ini文件读取Shiro配置并初始化安全框架。 它不执行任何安全检查。 权限检查,用户登录,协议检查等都委托给默认或自定义过滤器。 IniShiroFilter仅初始化它们。

文档和javadoc中都介绍了Ini配置。 Ini文件配置包含四个部分:

  • [main]部分包含Shiro初始化。 过滤器和自定义对象在此处配置。
  • [用户]部分定义用户,密码和角色。
  • [角色]部分将角色与权限相关联。
  • [urls]部分指定对应用程序页面(url)的访问权限。 通过将默认或自定义过滤器绑定到url来完成此操作。

将Apache Shiro依赖项添加到pom.xml:

<properties><shiro.version>1.1.0</shiro.version>
</properties>
<dependencies><dependency><groupid>org.apache.shiro</groupid><artifactid>shiro-core</artifactid><version>${shiro.version}</version></dependency><dependency><groupid>org.apache.shiro</groupid><artifactid>shiro-web</artifactid><version>${shiro.version}</version></dependency>
</dependencies>

创建Shiro.ini文件并将其放在类路径中。 将web.xml配置为在每个请求之前调用IniShiroFilter:

<filter><filter-name>ShiroFilter</filter-name><filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class><init-param><param-name>configPath</param-name><param-value>classpath:Shiro.ini</param-value></init-param>
</filter><filter-mapping><filter-name>ShiroFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

创建登录页面

登录页面是带有提交按钮,用户名和密码字段的简单html页面。 登录功能默认为Shiro authc过滤器处理。 Authc过滤器仅允许登录用户访问url。 如果用户未登录,过滤器会将其重定向到登录页面。

登录页面上的表单名称必须为“ loginform”,其提交方法必须为“ post”。 创建login.jsp页面:

<form name="loginform" action="" method="post">
<table align="left" border="0" cellspacing="0" cellpadding="3"><tr><td>Username:</td><td><input type="text" name="user" maxlength="30"></td></tr><tr><td>Password:</td><td><input type="password" name="pass" maxlength="30"></td></tr><tr><td colspan="2" align="left"><input type="checkbox" name="remember"><font size="2">Remember Me</font></td></tr><tr><td colspan="2" align="right"><input type="submit" name="submit" value="Login"></td></tr>
</table> 
</form>

为所有应用程序页面启用authc过滤器:

[main] 
# specify login page
authc.loginUrl = /simpleshirosecuredapplication/account/login.jsp# name of request parameter with username; if not present filter assumes 'username'
authc.usernameParam = user
# name of request parameter with password; if not present filter assumes 'password'
authc.passwordParam = pass
# does the user wish to be remembered?; if not present filter assumes 'rememberMe'
authc.rememberMeParam = remember# redirect after successful login
authc.successUrl  = /simpleshirosecuredapplication/account/personalaccountpage.jsp[urls]
# enable authc filter for all application pages
/simpleshirosecuredapplication/**=authc

更新: Shiro自动执行上下文相关的路径匹配。 由于SimpleShiroSecuredApplication没有设置上下文路径,因此Shiro.ini中的完整路径是必需的。 但是,如果应用程序上下文路径为/ simpleshirosecuredapplication,则路径可能是相对的:例如,简单的/ ** = authc或/account/personalaccountpage.jsp。

由于通过网络发送未加密的用户名和密码是不安全的,因此我们应强制使用ssl登录。 SSL过滤器正是这样做的。 它具有一个可选参数:ssl端口号。 如果省略port参数,它将使用默认的ssl端口443。

在Shiro中配置ssl之前,我们必须在Web服务器上启用它。 具体操作取决于Web服务器。 我们展示了如何在Jetty中启用它。 首先,使用自签名证书创建密钥库:

keytool -genkey -keyalg RSA -alias jetty -keystore keystore -storepass secret -validity 360 -keysize 2048

回答所有问题,最后按Enter键,以便密钥库密码和密钥密码相同。

其次,将密钥库添加到项目中,并将Jetty配置为使用ssl。 Java代码在AbstractContainerTest类中可用。

现在,可以在Shiro.ini中配置ssl过滤器:

[urls]
# force ssl for login page
/simpleshirosecuredapplication/account/login.jsp=ssl[8443],authc
# enable authc filter for the all application pages; as Shiro reads urls from up to down, must be last
/simpleshirosecuredapplication/**=authc

配置用户和密码

现在,SimpleShiroSecuredApplication仅适用于登录用户。 现在,我们需要添加一些用户,以便人们可以登录。配置在Shiro.ini文件的[用户]部分中完成。 部分条目的格式为:

username = password, roleName1, roleName2, ..., roleNameN

以下部分创建七个用户,所有用户都具有相同的密码“ heslo”:

[users]
administrator=heslo,Administrator
friendlyrepairmen=heslo,repairmen
unfriendlyrepairmen=heslo,repairmen
mathematician=heslo,scientist
physicien=heslo,scientist
productsales=heslo,sales
servicessales=heslo,sales

现在可以登录到应用程序。 但是,如果用户犯了错误,则不会显示任何合理的错误消息。 此外,密码存储在纯文本文件中。

错误处理

如果用户在登录时出错,则Shiro会将其重定向回登录页面。 该页面看起来与以前完全相同,这可能会使用户感到困惑。

新要求:每次尝试登录失败后,显示错误消息。

每当发生身份验证错误时,都会引发异常。 默认情况下,表单身份验证过滤器会捕获异常并将其类名称存储在request参数中。 由于我们希望自定义发送到页面的数据,因此我们必须扩展FormAuthenticationFilter并重写setFailureAttribute方法:

@Override
protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {String message = ae.getMessage();request.setAttribute(getFailureKeyAttribute(), message);
}

用VerboseFormAuthenticationFilter替换表单授权过滤器,并将其配置为使用'simpleShiroApplicationLoginFailure'请求属性来保存错误信息:

[main]
# replace form authentication filter with verbose filter 
authc = org.meri.simpleshirosecuredapplication.servlet.VerboseFormAuthenticationFilter
# request parameter with login error information; if not present filter assumes 'shiroLoginFailure'
authc.failureKeyAttribute=simpleShiroApplicationLoginFailure

在login.jsp页面中显示错误:

<% String errorDescription = (String) request.getAttribute("simpleShiroApplicationLoginFailure");if (errorDescription!=null) {
%>
Login attempt was unsuccessful: <%=errorDescription%>
<% }
%>

当心:真实的应用程序不应显示太多的登录错误信息。 消息“尝试登录失败。” 没有更多信息通常就足够了。

散列密码

当前应用程序版本的所有密码均以纯文本格式存储。 最好只存储和比较密码哈希。

负责身份验证的对象称为领域 。 默认情况下,Shiro使用带可插入密码匹配器的IniRealm来比较密码。 我们将用ini的SHA-256哈希替换ini中的密码,并将IniRealm配置为使用SHA-256哈希匹配器。

生成密码的SHA-256哈希:

import org.apache.shiro.crypto.hash.Sha256Hash;public static void main(String[] args) {Sha256Hash sha256Hash = new Sha256Hash("heslo");System.out.println(sha256Hash.toHex());
}

将Shiro配置为比较密码哈希而不是密码本身:

[main] 
# define matcher matching hashes instead of passwords
sha256Matcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
sha256Matcher.hashAlgorithmName=SHA-256# enable matcher in iniRealm (object responsible for authentication)
iniRealm.credentialsMatcher = $sha256Matcher

用密码哈希替换用户密码:

[users]
administrator=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, Administrator
friendlyrepairmen=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, repairmen
unfriendlyrepairmen=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, repairmen
mathematician=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005, scientist
physicien=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005,  scientist
productsales=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005,        sales
servicessales=56b1db8133d9eb398aabd376f07bf8ab5fc584ea0b8bd6a1770200cb613ca005,  sales

注意:无法在ini配置中指定salt。

创建注销页面

具有登录功能的任何应用程序也应具有注销功能。 使用Shiro注销当前用户很容易,请使用以下命令:

//acquire currently logged user and log him out
SecurityUtils.getSubject().logout();

注销页面如下所示:

<%@ page import="org.apache.shiro.SecurityUtils" %>
<% SecurityUtils.getSubject().logout();%>
You have succesfully logged out.

添加授权

我们通过向应用程序添加授权来结束第一部分。 我们从限制用户访问页面开始。 任何用户都不能看到其他部门的页面。 由于用户仍然能够使用“所有应用程序功能”页面或在浏览器中编辑URL来执行任何操作,因此这仅为项目提供了部分安全性。 我们将其称为页面级授权。

然后,我们限制了用户自己执行操作的能力。 即使用户打开“所有应用程序功能”页面或在浏览器中编辑URL,也将只允许他执行其部门特定的功能。 我们将其称为功能级别授权。

新要求:用户无法查看不属于他的部门的页面。 用户只能执行其部门职能。 以前的规则唯一的例外是管理员,管理员可以执行管理和修复功能。

页面授权

页面级授权是通过角色过滤器完成的。 过滤器的参数部分可以包含任意数量的角色。 登录的用户只有拥有所有提供的角色,才能访问页面。

像往常一样,在Shiro.ini文件中配置角色过滤器:

[urls]
# force ssl for login page
/simpleshirosecuredapplication/account/login.jsp=ssl[8443],authc# only users with some roles are allowed to use role-specific pages 
/simpleshirosecuredapplication/repairmen/**=authc, roles[repairman]
/simpleshirosecuredapplication/sales/**=authc, roles[sales]
/simpleshirosecuredapplication/scientists/**=authc, roles[scientist]
/simpleshirosecuredapplication/adminarea/**=authc, roles[Administrator]# enable authc filter for the all application pages; as Shiro reads urls from up to down, must be last
/simpleshirosecuredapplication/**=authc

测试安全性是否有效:以任何销售用户身份登录,单击“主页”,然后单击“维修人员页面”链接。 您会看到一个难看的错误。

我们完成页面授权并将错误替换为重定向到错误页面。 默认的Shiro过滤器具有属性validateUrl。 如果发生未经授权的访问,过滤器会将用户重定向到指定的url。

[main]
# redirect to an error page if user does not have access rights
roles.unauthorizedUrl = /simpleshirosecuredapplication/account/accessdenied.jsp

accessdenied.jsp:

<body>
Sorry, you do not have access rights to that area.
</body>

功能授权

现在所有部门页面均已安全。 但是,任何用户仍可以在“所有应用程序功能”页面上执行任何功能。 此外,任何登录的用户都可以编辑url,从而可以执行任何操作。 例如,如果您以销售人员身份登录并将https:// localhost:8443 / simpleshirosecuredapplication / masterservlet?action = MANAGE_REPAIRMEN放入url中,则该应用程序也将执行管理修复功能(然后将引发空指针异常,但存在安全漏洞)已经完成了)。

我们为每个功能分配唯一的权限 。 它们分为几组:

  • 所有权限都在“功能”组中,
  • 所有管理权限都在“管理”组中,
  • 所有修复权限都在“修复”组中,
  • 所有销售权限都在“销售”组中,
  • 所有科学许可都在“科学”组中。

Shiro支持表示为字符串的多级权限。 级别用符号“:”分隔。 例如,“功能:管理:修理工”具有三个级别:“功能”,“管理”和“修理工”。 多级权限允许轻松进行权限分组。 例如,科学组属于功能组,并且包含三个权限:

  • 职能:科学:研究,
  • 功能:科学:写作文章,
  • 职能:科学:准备谈话。

操作将在完成记录的用户权限之前对其进行验证:

public String doIt() {String neededPermission = getNeededPermission();// acquire logged user and check permissionif (SecurityUtils.getSubject().isPermitted(neededPermission))return "Function " + getName() + " run succesfully.";throw new UnauthorizedException("Logged user does not have " + neededPermission + " permission");
}

注意:实现相同目标的另一种方法是通过注释。

PerformFunctionAndGoBackServlet servlet捕获授权异常并将其转换为错误消息:

private String performAction(String actionName) {try {Actions action = findAction(actionName);String result = action == null ? null : action.doIt();log.debug("Performed function with result: " + result);return result;} catch (ShiroException ex) {log.debug("Function failed with " + ex.getMessage() + " message.");return "Error: " + ex.getMessage();}
}

最后,我们需要在Shiro.ini文件中配置角色的权限。 Shiro支持通配符以获得多级权限。 因此,我们不必分别指定每个部门的许可:

[roles]
# members of departments should be able to perform all departmental functions
sales=functions:sale:*
scientist=functions:science:*
repairman=functions:repair:*# administrators are able to do all management functions and repair functions
Administrator=functions:manage:*,functions:repair:*

您现在可以在“所有应用程序功能”页面上尝试功能。 如果登录的用户没有所需的权限,则会在页面顶部显示错误消息。 此外,如果您以销售人员身份登录并尝试入侵https:// localhost:8443 / simpleshirosecuredapplication / masterservlet?action = MANAGE_REPAIRMEN,则会在控制台中看到错误消息(而不是成功消息)。

结束

最终的应用程序可以在Github上的“ static_authentication_and_authorization”分支中找到。

在第二部分中,我们将创建自定义领域,并将用户,密码,角色和权限从ini文件移动到数据库。 第三部分专门介绍Apache Shiro加密软件包。

参考: Apache Shiro第1部分– JCG合作伙伴 Maria Jurcovicova的基础知识,来自This is Stuff博客。


翻译自: https://www.javacodegeeks.com/2012/05/apache-shiro-part-1-basics.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372731.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javascript 之Object内置对象

Object.defineProperty(obj, prop, descriptor)转载于:https://www.cnblogs.com/lihuali/p/5632460.html

java员工编号程序_用JAVA编写一个employee类 为员工自动产生员工号

差不多就是这个感觉..class Employee {/*** param args*/private int number;private String name;private String birthday;static int IDnumber0;public Employee(String name,String birthday){IDnumber;this.setNumber(IDnumber);this.setName(name);this.setBirthday(birt…

分解质因数-洛谷P3200 [HNOI2009]有趣的数列

https://www.luogu.org/problem/show?pid3200 首先&#xff0c;我们不能保证要求的数的逆元和模域互质&#xff1b; 所以我们要用分解质因数来抵消除法&#xff1b; 其实逆元的话即使可行也会超时&#xff1b; 那么我转载了&#xff0c;实在没什么可以说的&#xff1b; 另…

Java中的安全加密

上一次我写关于密码学的文章时 &#xff0c;我概述了Apache Shiro加密API&#xff0c;并展示了如何使用其两个对称密码。 我还写道&#xff1a;“您不需要在应用程序中对敏感数据进行加密和解密。” 我了解了更多有关密码的知识&#xff0c;发现您需要了解更多信息。 我写的内容…

真机调试问题

1.拔掉插头重新插入 2.转载于:https://www.cnblogs.com/sanvow/p/5633976.html

vsftp

它的配置文件在/etc/vsftpd/vsftpd.conf在里面加入 anonymous_enableYES &#xff03;允许匿名用户登录FTPanon_upload_enableYES &#xff03;打开匿名用户的上传权限anon_mkdir_write_enableYES &#xff03;打开匿名用户创建目录的权限anon_other_write_enableYES …

java scrollpane源码_JScrollPane用法 Java实例

时间&#xff1a;2019-10-07概述&#xff1a;JScrollPane 滚动条在Java中使用JScrollPane的例子&#xff0c;特别是滚动条的设置等&#xff0c;程序代码中将设置水平与垂直表头、设置scrollPane的边角图案、设置scrollPane的边框凹陷立体边框。适时水平滚动轴的参数设置等内容&…

ANTLR教程– Hello Word

Antlr代表另一种语言识别工具。 该工具能够为任何计算机语言生成编译器或解释器。 除了明显的用途&#xff08;例如需要解析一种真正的“大型”编程语言&#xff0c;例如Java&#xff0c;PHP或SQL&#xff09;外&#xff0c;它还可以帮助执行更小&#xff0c;更常见的任务。 每…

centOS 6.5安装python和nginx

一、安装python3.5 1、安装python3.5 2、安装pip并升级到最新 下载wget --no-check-certificate https://github.com/pypa/pip/archive/1.5.5.tar.gz 注意&#xff1a;wget获取https的时候要加上&#xff1a;--no-check-certificate tar zvxf 1.5.5.tar.gz #解压文件 cd pip…

rabbitmq 学习-9- RpcClient发送消息和同步接收消息原理

rabbitmq 学习-9- RpcClient发送消息和同步接收消息原理 转载于:https://www.cnblogs.com/gotodsp/p/6532824.html

汇编写java模块_java – maven汇编插件moduleset源指令不包括任何文件,不符合附带的模块...

我有一个多模块的maven项目,我正在尝试获取组件插件的moduleset源部分.我有模块“module_parent”,“module_a”和“module_assembly”.module_a和module_assembly是module_parent的子项.module_assembly对module_a有一个声明的pom依赖关系.module_assmebly具有程序集插件,asse…

用于RIA的JavaFX 2与HTML5

这些天来&#xff0c;我们正在启动一个新项目&#xff0c;以实现Rich Internet Application&#xff08;RIA&#xff09; 。 第一个问题是&#xff1a;我们应该使用哪些技术和框架&#xff1f; 后端将是Java或其他现代JVM语言&#xff0c;因为我们主要是经验丰富的Java开发人员…

插件化编程实现的一份糖炒栗子~~

迷茫的原因是因为想得太多&#xff0c;做得太少。因为只是 想 真的很容易&#xff0c;转瞬之间就会产生无数个念头&#xff0c;或许是该做点什么了吧。 但是整个人都是懒的&#xff0c;是废的&#xff0c;是大脑控制不住自己的行为的。解决方案唯有一步一步的去把行为变成习惯。…

用C#来学习唐诗三百首和全唐诗

Begin 最近把项目做完了&#xff0c;闲来无事&#xff0c;就想做点好玩的事情&#xff0c;刚好前几天下载了【唐诗三百首】和【全唐诗】这两个txt文件&#xff0c;正好用C#来整理一下。 然后导出QData格式&#xff0c;可以给其他软件读取。 以后弄个开机自动显示一句诗&#xf…

JRockit JRCMD教程

本文将为您提供概述和教程&#xff0c;说明如何使用jrcmd工具对JRockit Java Heap问题进行初始分析和问题隔离。 将来的文章中将介绍使用JRockit任务控制和堆转储分析&#xff08;仅限JRockit R28 版&#xff09;的更深入的分析和教程。 有关JRockit Java堆空间的快速概述&…

sts java配置tomcat_STS配置Tomcat.9.0

今天&#xff0c;心血来潮&#xff0c;弄了一下STS,按着建立WEB项目的方式建立工程。一、新建工程(FILE --NEW--Dynamic Web project)二、输入项目名称&#xff0c;TestWeb&#xff0c;然后下一步&#xff0c;点击FInish.三、新建index.jsp并打开index.jsp,书写测试成功&#x…

javaweb国际化

根据数据的类型不同&#xff0c;国际化分为2类&#xff1a;静态数据国际化和动态数据的国际化。 静态数据&#xff0c;包括 “标题”、“用户名”、“密码”这样的文字数据。 动态数据&#xff0c;包括日期、货币等可以动态生成的数据。 国际化涉及到java.util.Locale和java.ut…

20145335郝昊《网络攻防》Bof逆向基础——ShellCode注入与执行

20145335郝昊《网络攻防》Bof逆向基础——ShellCode注入与执行 实验原理 关于ShellCode&#xff1a;ShellCode是一段代码&#xff0c;作为数据发送给受攻击服务器&#xff0c;是溢出程序和蠕虫病毒的核心&#xff0c;一般可以获取权限。我们将代码存储到对方的堆栈中&#xff0…

Java枚举益智游戏

假设我们有以下代码&#xff1a; enum Case {CASE_ONE,CASE_TWO,CASE_THREE;private static final int counter;private int valueDependsOnCounter;static {int sum 0;for(int i 0; i<10; i) {sum i;}counter sum;} Case() {this.valueDependsOnCounter counter*counte…

jp在java中无法编译_JPanal上加图片的问题!

JPanal上加图片的问题&#xff01;import java.awt.BorderLayout;import java.awt.Dimension;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.*;import java.awt.*;public class Frame1 extends JFrame {JPanel contentPane;JLabel jLabel1 new JLa…